﻿#include "stdafx.h"
namespace LK
{
	PString BitPtr::ToString(index_t t)
	{
		LPWSTR str;
		if (t == 0)
		{
			str = new WCHAR[sizeof(size_t) * 2 + 5];
			str[0] = '0'; str[1] = 'x'; str[sizeof(size_t) * 2 + 2] = '-'; str[sizeof(size_t) * 2 + 3] = '0' + bitMove % 8; str[sizeof(size_t) * 2 + 4] = 0;
			size_t pv = ptrValue + bitMove / 8;
			for (index_t i = sizeof(size_t) * 2 + 1; i > 1; --i)
			{
				str[i] = pv % 16;
				if (str[i] > 9)str[i] += 'A' - 10;
				else str[i] += '0';
				pv /= 16;
			}
			t = sizeof(size_t) * 2 + 4;
		}
		else if (t > 0)
		{
			str = new WCHAR[t + 1]; str[t] = 0;
			BitPtr tmp(*this);
			for (index_t i = t; i != 0;) { --i; str[i] = '0' + (tmp++).Get(); }
		}
		else
		{
			str = new WCHAR[-t + 1]; str[-t] = 0;
			BitPtr tmp(*this);
			for (index_t i = t; i != 0;) { ++i; str[-i] = '0' + (tmp--).Get(); }
			t = -t;
		}
		return new LK::String(t, str, NULL);
	}
	u64 Bits::Divide(u64 high64, u64 low64, u64 num, u64*p)
	{
		u64 nh;
		u64 nl;
		if (num < 0x100000000)
		{
			nh = ((u64)(high64 % num) << 32) | (low64 >> 32);
			nl = ((u64)(nh % num) << 32) | (u32)low64;
			if (p)*p = nl % num;
			return ((nh / num) << 32) | (nl / num);
		}
		if ((u32)num == 0)
		{
			nh = num >> 32;
			nl = ((u64)(high64 % nh) << 32) | (low64 >> 32);
			if (p)*p = (((u64)(nl%nh)) << 32) | ((u32)low64);
			return ((high64 / nh) << 32) | (nl / nh);
		}
		//前导0
		size_t lzc = LeftZeroCount(num);
		u64 nnum = num << lzc;
		nl = (u32)nnum;
		nh = nnum >> 32;
		//试商除数
		u64 nhigh = nh + 1;
		u64 q2 = nnum << 32;
		//试商
		u64 q1 = high64 / nhigh;
		//检验
		u64 tl = (u32)q1*nl;
		u64 th = (q1 >= 0x100000000) ? (nl + q1*nh + (tl >> 32)) : (q1*nh + (tl >> 32));
		tl <<= 32;
		if (low64 < tl)high64--;
		low64 -= tl;
		high64 -= th;
		while (high64 > nh)
		{
			high64 -= (low64 >= q2 ? nh : nhigh);
			low64 -= q2;
			q1++;
		}
		if (high64 == nh&&low64 >= q2) { low64 -= q2; high64 = 0; q1++; }

		//第二轮试商
		q2 = ((high64 << 32) | (low64 >> 32)) / nhigh;
		//第二轮检验
		tl = (u32)q2*nl;
		th = ((q2 >= 0x100000000) ? nl : 0) + q2*nh + (tl >> 32);
		tl = (u32)tl | (th << 32);
		th >>= 32;
		if (low64 < tl)high64--;
		low64 -= tl;
		high64 -= th;
		if (low64 >= nnum) { low64 -= nnum; ++q2; }
		if (high64 != 0)
		{
			low64 -= nnum; ++q2;
			if (low64 >= nnum) { low64 -= nnum; ++q2; }
		}
		//输出结果
		if (lzc == 0)
		{
			if (p)*p = low64;
			return (q1 << 32) | q2;
		}
		if (p)*p = low64%num;
		return (q1 << (32 + lzc)) | (q2 << lzc) | (low64 / num);
	}
	index_t Bits::_LeftZeroCount32(u32 z)
	{
		if (z > 0x0000ffff)
		{
			if (z > 0x00ffffff)
			{
				if (z > 0x0fffffff)
				{
					if (z > 0x3fffffff)
					{
						if (z > 0x7fffffff)return 0; return 1;
					}		if (z > 0x1fffffff)return 2; return 3;
				}		if (z > 0x03ffffff)
				{
					if (z > 0x07ffffff)return 4; return 5;
				}		if (z > 0x01ffffff)return 6; return 7;
			}		if (z > 0x000fffff)
			{
				if (z > 0x003fffff)
				{
					if (z > 0x007fffff)return 8; return 9;
				}		if (z > 0x001fffff)return 10; return 11;
			}		if (z > 0x0003ffff)
			{
				if (z > 0x0007ffff)return 12; return 13;
			}		if (z > 0x0001ffff)return 14; return 15;
		}		if (z > 0x000000ff)
		{
			if (z > 0x00000fff)
			{
				if (z > 0x00003fff)
				{
					if (z > 0x00007fff)return 16; return 17;
				}		if (z > 0x00001fff)return 18; return 19;
			}		if (z > 0x000003ff)
			{
				if (z > 0x000007ff)return 20; return 21;
			}		if (z > 0x000001ff)return 22; return 23;
		}		if (z > 0x0000000f)
		{
			if (z > 0x0000003f)
			{
				if (z > 0x0000007f)return 24; return 25;
			}		if (z > 0x0000001f)return 26; return 27;
		}		if (z > 0x00000003)
		{
			if (z > 0x00000007)return 28; return 29;
		}		if (z > 0x00000001)return 30; return z != 0 ? 31 : 32;
	}
	index_t Bits::_LeftZeroCount64(u64 i)
	{
		if (i < 0x0000000100000000)//很有意思的感觉，呵呵
		{
			if (i < 0x0000000000010000)
			{
				if (i < 0x0000000000000100)
				{
					if (i < 0x0000000000000010)
					{
						if (i < 0x0000000000000004)
						{
							if (i < 0x0000000000000002)return 64 - (int)i; return 62;
						}       if (i < 0x0000000000000008)return 61; return 60;
					}       if (i < 0x0000000000000040)
					{
						if (i < 0x0000000000000020)return 59; return 58;
					}       if (i < 0x0000000000000080)return 57; return 56;
				}       if (i < 0x0000000000001000)
				{
					if (i < 0x0000000000000400)
					{
						if (i < 0x0000000000000200)return 55; return 54;
					}       if (i < 0x0000000000000800)return 53; return 52;
				}       if (i < 0x0000000000004000)
				{
					if (i < 0x0000000000002000)return 51; return 50;
				}       if (i < 0x0000000000008000)return 49; return 48;
			}       if (i < 0x0000000001000000)
			{
				if (i < 0x0000000000100000)
				{
					if (i < 0x0000000000040000)
					{
						if (i < 0x0000000000020000)return 47; return 46;
					}       if (i < 0x0000000000080000)return 45; return 44;
				}       if (i < 0x0000000000400000)
				{
					if (i < 0x0000000000200000)return 43; return 42;
				}       if (i < 0x0000000000800000)return 41; return 40;
			}       if (i < 0x0000000010000000)
			{
				if (i < 0x0000000004000000)
				{
					if (i < 0x0000000002000000)return 39; return 38;
				}       if (i < 0x0000000008000000)return 37; return 36;
			}       if (i < 0x0000000040000000)
			{
				if (i < 0x0000000020000000)return 35; return 34;
			}       if (i < 0x0000000080000000)return 33; return 32;
		}       if (i < 0x0001000000000000)
		{
			if (i < 0x0000010000000000)
			{
				if (i < 0x0000001000000000)
				{
					if (i < 0x0000000400000000)
					{
						if (i < 0x0000000200000000)return 31; return 30;
					}       if (i < 0x0000000800000000)return 29; return 28;
				}       if (i < 0x0000004000000000)
				{
					if (i < 0x0000002000000000)return 27; return 26;
				}       if (i < 0x0000008000000000)return 25; return 24;
			}       if (i < 0x0000100000000000)
			{
				if (i < 0x0000040000000000)
				{
					if (i < 0x0000020000000000)return 23; return 22;
				}       if (i < 0x0000080000000000)return 21; return 20;
			}       if (i < 0x0000400000000000)
			{
				if (i < 0x0000200000000000)return 19; return 18;
			}       if (i < 0x0000800000000000)return 17; return 16;
		}       if (i < 0x0100000000000000)
		{
			if (i < 0x0010000000000000)
			{
				if (i < 0x0004000000000000)
				{
					if (i < 0x0002000000000000)return 15; return 14;
				}       if (i < 0x0008000000000000)return 13; return 12;
			}       if (i < 0x0040000000000000)
			{
				if (i < 0x0020000000000000)return 11; return 10;
			}       if (i < 0x0080000000000000)return 9; return 8;
		}       if (i < 0x1000000000000000)
		{
			if (i < 0x0400000000000000)
			{
				if (i < 0x0200000000000000)return 7; return 6;
			}       if (i < 0x0800000000000000)return 5; return 4;
		}       if (i < 0x4000000000000000)
		{
			if (i < 0x2000000000000000)return 3; return 2;
		}       if (i < 0x8000000000000000)return 1; return 0;
	}
	index_t Bits::RightZeroCount64(u64 i)
	{
		if (i == 0)return 64; if ((i & 0xffffffff) != 0)//小于32
		{
			if ((i & 0xffff) != 0)//小于16
			{
				if ((i & 0xff) != 0)//小于8
				{
					if ((i & 0xf) != 0)//小于4
					{
						if ((i & 0x3) != 0)//小于2
						{
							if ((i & 0x1) != 0)return 0; return 1;
						}		if ((i & 0x7) != 0)return 2; return 3;
					}		if ((i & 0x3f) != 0)
					{
						if ((i & 0x1f) != 0)return 4; return 5;
					}		if ((i & 0x7f) != 0)return 6; return 7;
				}		if ((i & 0xfff) != 0)
				{
					if ((i & 0x3ff) != 0)
					{
						if ((i & 0x1ff) != 0)return 8; return 9;
					}		if ((i & 0x7ff) != 0)return 10; return 11;
				}		if ((i & 0x3fff) != 0)
				{
					if ((i & 0x1fff) != 0)return 12; return 13;
				}		if ((i & 0x7fff) != 0)return 14; return 15;
			}		if ((i & 0xffffff) != 0)
			{
				if ((i & 0xfffff) != 0)
				{
					if ((i & 0x3ffff) != 0)
					{
						if ((i & 0x1ffff) != 0)return 16; return 17;
					}		if ((i & 0x7ffff) != 0)return 18; return 19;
				}		if ((i & 0x3fffff) != 0)
				{
					if ((i & 0x1fffff) != 0)return 20; return 21;
				}		if ((i & 0x7fffff) != 0)return 22; return 23;
			}		if ((i & 0xfffffff) != 0)
			{
				if ((i & 0x3ffffff) != 0)
				{
					if ((i & 0x1ffffff) != 0)return 24; return 25;
				}		if ((i & 0x7ffffff) != 0)return 26; return 27;
			}		if ((i & 0x3fffffff) != 0)
			{
				if ((i & 0x1fffffff) != 0)return 28; return 29;
			}		if ((i & 0x7fffffff) != 0)return 30; return 31;
		}		if ((i & 0xffffffffffff) != 0)
		{
			if ((i & 0xffffffffff) != 0)
			{
				if ((i & 0xfffffffff) != 0)
				{
					if ((i & 0x3ffffffff) != 0)
					{
						if ((i & 0x1ffffffff) != 0)return 32; return 33;
					}		if ((i & 0x7ffffffff) != 0)return 34; return 35;
				}		if ((i & 0x3fffffffff) != 0)
				{
					if ((i & 0x1fffffffff) != 0)return 36; return 37;
				}		if ((i & 0x7fffffffff) != 0)return 38; return 39;
			}		if ((i & 0xfffffffffff) != 0)
			{
				if ((i & 0x3ffffffffff) != 0)
				{
					if ((i & 0x1ffffffffff) != 0)return 40; return 41;
				}		if ((i & 0x7ffffffffff) != 0)return 42; return 43;
			}		if ((i & 0x3fffffffffff) != 0)
			{
				if ((i & 0x1fffffffffff) != 0)return 44; return 45;
			}		if ((i & 0x7fffffffffff) != 0)return 46; return 47;
		}		if ((i & 0xffffffffffffff) != 0)
		{
			if ((i & 0xfffffffffffff) != 0)
			{
				if ((i & 0x3ffffffffffff) != 0)
				{
					if ((i & 0x1ffffffffffff) != 0)return 48; return 49;
				}		if ((i & 0x7ffffffffffff) != 0)return 50; return 51;
			}		if ((i & 0x3fffffffffffff) != 0)
			{
				if ((i & 0x1fffffffffffff) != 0)return 52; return 53;
			}		if ((i & 0x7fffffffffffff) != 0)return 54; return 55;
		}		if ((i & 0xfffffffffffffff) != 0)
		{
			if ((i & 0x3ffffffffffffff) != 0)
			{
				if ((i & 0x1ffffffffffffff) != 0)return 56; return 57;
			}		if ((i & 0x7ffffffffffffff) != 0)return 58; return 59;
		}		if ((i & 0x3fffffffffffffff) != 0)
		{
			if ((i & 0x1fffffffffffffff) != 0)return 60; return 61;
		}		if ((i & 0x7fffffffffffffff) != 0)return 62; return 63;
	}
	index_t Bits::RightZeroCount32(u32 i)
	{
		if (i == 0)return 32;
		if ((i & 0xffff) != 0)//小于16
		{
			if ((i & 0xff) != 0)//小于8
			{
				if ((i & 0xf) != 0)//小于4
				{
					if ((i & 0x3) != 0)//小于2
					{
						if ((i & 0x1) != 0)return 0; return 1;
					}		if ((i & 0x7) != 0)return 2; return 3;
				}		if ((i & 0x3f) != 0)
				{
					if ((i & 0x1f) != 0)return 4; return 5;
				}		if ((i & 0x7f) != 0)return 6; return 7;
			}		if ((i & 0xfff) != 0)
			{
				if ((i & 0x3ff) != 0)
				{
					if ((i & 0x1ff) != 0)return 8; return 9;
				}		if ((i & 0x7ff) != 0)return 10; return 11;
			}		if ((i & 0x3fff) != 0)
			{
				if ((i & 0x1fff) != 0)return 12; return 13;
			}		if ((i & 0x7fff) != 0)return 14; return 15;
		}		if ((i & 0xffffff) != 0)
		{
			if ((i & 0xfffff) != 0)
			{
				if ((i & 0x3ffff) != 0)
				{
					if ((i & 0x1ffff) != 0)return 16; return 17;
				}		if ((i & 0x7ffff) != 0)return 18; return 19;
			}		if ((i & 0x3fffff) != 0)
			{
				if ((i & 0x1fffff) != 0)return 20; return 21;
			}		if ((i & 0x7fffff) != 0)return 22; return 23;
		}		if ((i & 0xfffffff) != 0)
		{
			if ((i & 0x3ffffff) != 0)
			{
				if ((i & 0x1ffffff) != 0)return 24; return 25;
			}		if ((i & 0x7ffffff) != 0)return 26; return 27;
		}		if ((i & 0x3fffffff) != 0)
		{
			if ((i & 0x1fffffff) != 0)return 28; return 29;
		}		if ((i & 0x7fffffff) != 0)return 30; return 31;
	}
	index_t Bits::RightOneCount64(u64 i)
	{
		if ((i & 0xffffffff) != 0xffffffff)
		{
			if ((i & 0xffff) != 0xffff)
			{
				if ((i & 0xff) != 0xff)
				{
					if ((i & 0x0f) != 0x0f)
					{
						if ((i & 0x03) != 0x03)
						{
							if (i & 1)return 1; return 0;
						}	if (i & 0x4)return 3;	return 2;
					}	if ((i & 0x30) != 0x30)
					{
						if (i & 0x10)return 5; return 4;
					}	if (i & 0x40)return 7; return 6;
				}	if ((i & 0x0f00) != 0x0f00)
				{
					if ((i & 0x0300) != 0x0300)
					{
						if (i & 0x100)return 9; return 8;
					}	if (i & 0x400)return 11; return 10;
				}	if ((i & 0x3000) != 0x3000)
				{
					if (i & 0x1000)return 13; return 12;
				}	if (i & 0x4000)return 15; return 14;
			}	if ((i & 0xff0000) != 0xff0000)
			{
				if ((i & 0x0f0000) != 0x0f0000)
				{
					if ((i & 0x030000) != 0x030000)
					{
						if (i & 0x010000)return 17; return 16;
					}	if (i & 0x40000)return 19; return 18;
				}	if ((i & 0x300000) != 0x300000)
				{
					if (i & 0x100000)return 21; return 20;
				}	if (i & 0x400000)return 23; return 22;
			}	if ((i & 0x0f000000) != 0x0f000000)
			{
				if ((i & 0x03000000) != 0x03000000)
				{
					if (i & 0x1000000)return 25;	return 24;
				}	if (i & 0x4000000)return 27; return 26;
			}	if ((i & 0x30000000) != 0x30000000)
			{
				if (i & 0x10000000)return 29; return 28;
			}	if (i & 0x40000000)return 31; return 30;
		}	if ((i & 0xffff00000000) != 0xffff00000000)
		{
			if ((i & 0xff00000000) != 0xff00000000)
			{
				if ((i & 0x0f00000000) != 0x0f00000000)
				{
					if ((i & 0x0300000000) != 0x0300000000)
					{
						if (i & 0x100000000)return 33; return 32;
					}	if (i & 0x400000000)return 35; return 34;
				}	if ((i & 0x3000000000) != 0x3000000000)
				{
					if (i & 0x1000000000)return 37; return 36;
				}	if (i & 0x4000000000)return 39; return 38;
			}	if ((i & 0x0f0000000000) != 0x0f0000000000)
			{
				if ((i & 0x030000000000) != 0x030000000000)
				{
					if (i & 0x10000000000)return 41; return 40;
				}	if (i & 0x40000000000)return 43; return 42;
			}	if ((i & 0x300000000000) != 0x300000000000)
			{
				if (i & 0x100000000000)return 45; return 44;
			}	if (i & 0x400000000000)return 47; return 46;
		}	if ((i & 0xff000000000000) != 0xff000000000000)
		{
			if ((i & 0x0f000000000000) != 0x0f000000000000)
			{
				if ((i & 0x03000000000000) != 0x03000000000000)
				{
					if (i & 0x01000000000000)return 49;	return 48;
				}	if (i & 0x4000000000000)return 51; return 50;
			}	if ((i & 0x30000000000000) != 0x30000000000000)
			{
				if (i & 0x10000000000000)return 53;	return 52;
			}	if (i & 0x40000000000000)return 55; return 54;
		}	if ((i & 0x0f00000000000000) != 0x0f00000000000000)
		{
			if ((i & 0x0300000000000000) != 0x0300000000000000)
			{
				if (i & 0x100000000000000)return 57; return 56;
			}	if (i & 0x400000000000000)return 59; return 58;
		}	if ((i & 0x3000000000000000) != 0x3000000000000000)
		{
			if (i & 0x1000000000000000)return 61;	return 60;
		}	if (i & 0x4000000000000000)return i == (u64)-1 ? 64 : 63; return 62;
	}
	void Bits::Copy64(u64* pDest, s64 destStartBitPositon, cu64* pSource, s64 sourceStartBitPositon, u64 bitsCount)
	{
		if (bitsCount == 0)return;
		if (sourceStartBitPositon < 0) { pSource += (sourceStartBitPositon - 63) / 64; sourceStartBitPositon &= 63; }
		else if (sourceStartBitPositon >= 64) { pSource += sourceStartBitPositon / 64; sourceStartBitPositon &= 63; }
		if (destStartBitPositon < 0) { pDest += (destStartBitPositon - 63) / 64; destStartBitPositon &= 63; }
		else if (destStartBitPositon >= 64) { pDest += destStartBitPositon / 64; destStartBitPositon &= 63; }
		if (sourceStartBitPositon == 0)
		{
			if (destStartBitPositon == 0)
			{
				u64* pEnd = (bitsCount >> 6) + pDest;
				while (pDest != pEnd)*pDest++ = *pSource++;
				if ((bitsCount &= 63) != 0)*pDest = (*pSource&(((u64)-1) >> (64 - bitsCount))) | (*pDest&(((u64)-1) << bitsCount));
				return;
			}
			u64* pEnd = ((bitsCount + destStartBitPositon) >> 6) + pDest;
			if (pEnd == pDest)
			{
				*pDest = (*pDest &(((((u64)-1) << (bitsCount + destStartBitPositon)) | (((u64)-1) >> (64 - destStartBitPositon)))))
					| ((*pSource&(((u64)-1) >> (64 - bitsCount))) << destStartBitPositon);
				return;
			}
			*pDest = (*pSource << destStartBitPositon) | (*pDest&(((u64)-1) >> (64 - destStartBitPositon)));
			while (++pDest != pEnd) { *pDest = (*pSource >> (64 - destStartBitPositon)) | (*(pSource + 1) << destStartBitPositon); ++pSource; }
			if ((bitsCount = (destStartBitPositon + bitsCount) & 63) != 0)
			{
				u64 tmp = (*pSource >> (64 - destStartBitPositon));
				if (bitsCount > (u64)destStartBitPositon)tmp |= *(pSource + 1) << destStartBitPositon;
				*pDest = (*pDest&(((u64)-1) << bitsCount)) | (tmp&(((u64)-1) >> (64 - bitsCount)));
			}
			return;
		}
		if (destStartBitPositon == 0)
		{
			u64* pEnd = (bitsCount >> 6) + pDest;
			while (pEnd != pDest)
			{
				*pDest++ = (*pSource >> sourceStartBitPositon) | (pSource[1] << (64 - sourceStartBitPositon));
				++pSource;
			}
			if ((bitsCount &= 63) != 0)
			{
				u64 tmp = *pSource >> sourceStartBitPositon;
				if (bitsCount + sourceStartBitPositon > 64)tmp |= (pSource[1] << (64 - sourceStartBitPositon));
				*pDest = (*pDest & (((u64)-1) << bitsCount)) | (tmp&(((u64)-1) >> (64 - bitsCount)));
			}
			return;
		}
		u64* pEnd = ((bitsCount + destStartBitPositon) >> 6) + pDest;
		if (pEnd == pDest)
		{
			u64 tmp = *pSource >> sourceStartBitPositon;
			if (bitsCount + sourceStartBitPositon > 64)tmp |= (pSource[1] << (64 - sourceStartBitPositon));
			*pDest = (*pDest &(((((u64)-1) << (bitsCount + destStartBitPositon)) | (((u64)-1) >> (64 - destStartBitPositon)))))
				| ((tmp&(((u64)-1) >> (64 - bitsCount))) << destStartBitPositon);
			return;
		}
		*pDest = (((*pSource >> sourceStartBitPositon) | (pSource[1] << (64 - sourceStartBitPositon))) << destStartBitPositon) | (*pDest&(((u64)-1) >> (64 - destStartBitPositon)));
		if (sourceStartBitPositon == destStartBitPositon)
		{
			while (++pDest != pEnd) { *pDest = *++pSource; }
			if ((bitsCount = (destStartBitPositon + bitsCount) & 63) != 0)
			{
				*pDest = (*pDest&(((u64)-1) << bitsCount)) | ((*(pSource + 1))&(((u64)-1) >> (64 - bitsCount)));
			}
			return;
		}
		sourceStartBitPositon -= destStartBitPositon;
		if (sourceStartBitPositon < 0)
		{
			sourceStartBitPositon = -sourceStartBitPositon;
			while (++pDest != pEnd)
			{
				*pDest = (*pSource >> (64 - sourceStartBitPositon)) | (*(pSource + 1) << sourceStartBitPositon);
				++pSource;
			}
			if ((bitsCount = (destStartBitPositon + bitsCount) & 63) != 0)
			{
				u64 tmp = *pSource >> (64 - sourceStartBitPositon);
				if (bitsCount > (u64)sourceStartBitPositon)tmp |= pSource[1] << sourceStartBitPositon;
				*pDest = (*pDest&(((u64)-1) << bitsCount)) | (tmp&(((u64)-1) >> (64 - bitsCount)));
			}
			return;
		}
		while (++pDest != pEnd)
		{
			++pSource;
			*pDest = (*pSource >> sourceStartBitPositon) | (*(pSource + 1) << (64 - sourceStartBitPositon));
		}
		if ((bitsCount = (destStartBitPositon + bitsCount) & 63) != 0)
		{
			u64 tmp = pSource[1] >> sourceStartBitPositon;
			if (bitsCount + sourceStartBitPositon > 64)tmp |= pSource[2] << (64 - sourceStartBitPositon);
			*pDest = (*pDest&(((u64)-1) << bitsCount)) | (tmp&(((u64)-1) >> (64 - bitsCount)));
		}
	}
	void Bits::Copy32(u32* pDest, s32 destStartBitPositon, cu32* pSource, s32 sourceStartBitPositon, u32 bitsCount)
	{
		if (bitsCount == 0)return;
		if (sourceStartBitPositon < 0) { pSource += (sourceStartBitPositon - 31) / 32; sourceStartBitPositon &= 31; }
		else if (sourceStartBitPositon >= 32) { pSource += sourceStartBitPositon / 32; sourceStartBitPositon &= 31; }
		if (destStartBitPositon < 0) { pDest += (destStartBitPositon - 31) / 32; destStartBitPositon &= 31; }
		else if (destStartBitPositon >= 32) { pDest += destStartBitPositon / 32; destStartBitPositon &= 31; }
		if (sourceStartBitPositon == 0)
		{
			if (destStartBitPositon == 0)
			{
				u32* pEnd = (bitsCount >> 5) + pDest;
				while (pDest != pEnd)*pDest++ = *pSource++;
				if ((bitsCount &= 31) != 0)*pDest = (*pSource&(((u32)-1) >> (32 - bitsCount))) | (*pDest&(((u32)-1) << bitsCount));
				return;
			}
			u32* pEnd = ((bitsCount + destStartBitPositon) >> 5) + pDest;
			if (pEnd == pDest)
			{
				*pDest = (*pDest &(((((u32)-1) << (bitsCount + destStartBitPositon)) | (((u32)-1) >> (32 - destStartBitPositon)))))
					| ((*pSource&(((u32)-1) >> (32 - bitsCount))) << destStartBitPositon);
				return;
			}
			*pDest = (*pSource << destStartBitPositon) | (*pDest&(((u32)-1) >> (32 - destStartBitPositon)));
			while (++pDest != pEnd) { *pDest = (*pSource >> (32 - destStartBitPositon)) | (*(pSource + 1) << destStartBitPositon); ++pSource; }
			if ((bitsCount = (destStartBitPositon + bitsCount) & 31) != 0)
			{
				u32 tmp = (*pSource >> (32 - destStartBitPositon));
				if (bitsCount > (u64)destStartBitPositon)tmp |= *(pSource + 1) << destStartBitPositon;
				*pDest = (*pDest&(((u32)-1) << bitsCount)) | (tmp&(((u32)-1) >> (32 - bitsCount)));
			}
			return;
		}
		if (destStartBitPositon == 0)
		{
			u32* pEnd = (bitsCount >> 5) + pDest;
			while (pEnd != pDest)
			{
				*pDest++ = (*pSource >> sourceStartBitPositon) | (pSource[1] << (32 - sourceStartBitPositon));
				++pSource;
			}
			if ((bitsCount &= 31) != 0)
			{
				u32 tmp = *pSource >> sourceStartBitPositon;
				if (bitsCount + sourceStartBitPositon > 32)tmp |= (pSource[1] << (32 - sourceStartBitPositon));
				*pDest = (*pDest & (((u32)-1) << bitsCount)) | (tmp&(((u32)-1) >> (32 - bitsCount)));
			}
			return;
		}
		u32* pEnd = ((bitsCount + destStartBitPositon) >> 5) + pDest;
		if (pEnd == pDest)
		{
			u32 tmp = *pSource >> sourceStartBitPositon;
			if (bitsCount + sourceStartBitPositon > 32)tmp |= (pSource[1] << (32 - sourceStartBitPositon));
			*pDest = (*pDest &(((((u32)-1) << (bitsCount + destStartBitPositon)) | (((u32)-1) >> (32 - destStartBitPositon)))))
				| ((tmp&(((u32)-1) >> (32 - bitsCount))) << destStartBitPositon);
			return;
		}
		*pDest = (((*pSource >> sourceStartBitPositon) | (pSource[1] << (32 - sourceStartBitPositon))) << destStartBitPositon) | (*pDest&(((u32)-1) >> (32 - destStartBitPositon)));
		if (sourceStartBitPositon == destStartBitPositon)
		{
			while (++pDest != pEnd) { *pDest = *++pSource; }
			if ((bitsCount = (destStartBitPositon + bitsCount) & 31) != 0)
			{
				*pDest = (*pDest&(((u32)-1) << bitsCount)) | ((*(pSource + 1))&(((u32)-1) >> (32 - bitsCount)));
			}
			return;
		}
		sourceStartBitPositon -= destStartBitPositon;
		if (sourceStartBitPositon < 0)
		{
			sourceStartBitPositon = -sourceStartBitPositon;
			while (++pDest != pEnd)
			{
				*pDest = (*pSource >> (32 - sourceStartBitPositon)) | (*(pSource + 1) << sourceStartBitPositon);
				++pSource;
			}
			if ((bitsCount = (destStartBitPositon + bitsCount) & 31) != 0)
			{
				u32 tmp = *pSource >> (32 - sourceStartBitPositon);
				if (bitsCount > (u64)sourceStartBitPositon)tmp |= pSource[1] << sourceStartBitPositon;
				*pDest = (*pDest&(((u32)-1) << bitsCount)) | (tmp&(((u32)-1) >> (32 - bitsCount)));
			}
			return;
		}
		while (++pDest != pEnd)
		{
			++pSource;
			*pDest = (*pSource >> sourceStartBitPositon) | (*(pSource + 1) << (32 - sourceStartBitPositon));
		}
		if ((bitsCount = (destStartBitPositon + bitsCount) & 31) != 0)
		{
			u32 tmp = pSource[1] >> sourceStartBitPositon;
			if (bitsCount + sourceStartBitPositon > 32)tmp |= pSource[2] << (32 - sourceStartBitPositon);
			*pDest = (*pDest&(((u32)-1) << bitsCount)) | (tmp&(((u32)-1) >> (32 - bitsCount)));
		}
	}
	void Bits::Move64(u64* pDest, s64 destStartBitPositon, cu64* pSource, s64 sourceStartBitPositon, u64 bitsCount)
	{
		if (bitsCount == 0)return;
		if (sourceStartBitPositon < 0) { pSource += (sourceStartBitPositon - 63) / 64; sourceStartBitPositon &= 63; }
		else if (sourceStartBitPositon >= 64) { pSource += sourceStartBitPositon / 64; sourceStartBitPositon &= 63; }
		if (destStartBitPositon < 0) { pDest += (destStartBitPositon - 63) / 64; destStartBitPositon &= 63; }
		else if (destStartBitPositon >= 64) { pDest += destStartBitPositon / 64; destStartBitPositon &= 63; }
		if (pDest <= pSource)
		{
			if (pDest < pSource || sourceStartBitPositon > destStartBitPositon) { Copy64(pDest, destStartBitPositon, pSource, sourceStartBitPositon, bitsCount); return; }
			if (sourceStartBitPositon == destStartBitPositon)return;
		}
		if (sourceStartBitPositon == 0)
		{
			if (destStartBitPositon == 0)
			{
				u64 bc = bitsCount & 63;
				u64 bm = bitsCount >> 6;
				u64* pEnd = bm + pDest;
				pSource += bm;
				if (bc != 0)*pEnd = (*pSource&(((u64)-1) >> (64 - bc))) | (*pEnd&(((u64)-1) << bc));
				while (pDest != pEnd)*--pEnd = *--pSource;
				return;
			}
			u64 bm = (destStartBitPositon + bitsCount) >> 6;
			u64* pEnd = bm + pDest;
			if (pEnd == pDest)
			{
				*pDest = (*pDest &(((((u64)-1) << (bitsCount + destStartBitPositon)) | (((u64)-1) >> (64 - destStartBitPositon)))))
					| ((*pSource&(((u64)-1) >> (64 - bitsCount))) << destStartBitPositon);
				return;
			}
			u64 bc = (destStartBitPositon + bitsCount) & 63;
			pSource += bm - 1;
			if (bc != 0)
			{
				u64 tmp = (*pSource >> (64 - destStartBitPositon));
				if (bc > (u64)destStartBitPositon)tmp |= pSource[1] << destStartBitPositon;
				*pEnd = (*pEnd&(((u64)-1) << bc)) | (tmp&(((u64)-1) >> (64 - bc)));
			}
			while (pDest != --pEnd) { --pSource; *pEnd = (*pSource >> (64 - destStartBitPositon)) | (*(pSource + 1) << destStartBitPositon); }
			*pDest = (*(pSource) << destStartBitPositon) | (*pDest&(((u64)-1) >> (64 - destStartBitPositon)));
			return;
		}
		if (destStartBitPositon == 0)
		{
			u64 bc = bitsCount & 63;
			u64 bm = bitsCount >> 6;
			u64* pEnd = bm + pDest;
			pSource += bm;
			if (bc != 0)
			{
				u64 tmp = *pSource >> sourceStartBitPositon;
				if (bc + sourceStartBitPositon > 64)tmp |= (pSource[1] << (64 - sourceStartBitPositon));
				*pEnd = (*pEnd & (((u64)-1) << bc)) | (tmp&(((u64)-1) >> (64 - bc)));
			}
			while (pEnd != pDest)
			{
				*--pEnd = (*(pSource - 1) >> sourceStartBitPositon) | (*pSource << (64 - sourceStartBitPositon));
				--pSource;
			}
			return;
		}
		u64 bm = (bitsCount + destStartBitPositon) >> 6;
		u64* pEnd = bm + pDest;
		if (pEnd == pDest)
		{
			u64 tmp = *pSource >> sourceStartBitPositon;
			if (bitsCount + sourceStartBitPositon > 64)tmp |= (pSource[1] << (64 - sourceStartBitPositon));
			*pDest = (*pDest &(((((u64)-1) << (bitsCount + destStartBitPositon)) | (((u64)-1) >> (64 - destStartBitPositon)))))
				| ((tmp&(((u64)-1) >> (64 - bitsCount))) << destStartBitPositon);
			return;
		}
		u64 bc = (bitsCount + destStartBitPositon) & 63;
		pSource += bm - 1;
		if (sourceStartBitPositon == destStartBitPositon)
		{
			if (bc != 0)
			{
				*pEnd = (*pEnd&(((u64)-1) << bc)) | ((*(pSource + 1))&(((u64)-1) >> (64 - bc)));
			}
			while (pDest != --pEnd) { *pEnd = *pSource--; }
		}
		else {
			s64 smov = sourceStartBitPositon - destStartBitPositon;
			if (smov < 0)
			{
				smov = -smov;
				if (bc != 0)
				{
					u64 tmp = *pSource >> (64 - smov);
					if (bc > (u64)smov)tmp |= pSource[1] << smov;
					*pEnd = (*pEnd&(((u64)-1) << bc)) | (tmp&(((u64)-1) >> (64 - bc)));
				}
				while (pDest != --pEnd)
				{
					--pSource;
					*pEnd = (*pSource >> (64 - smov)) | (pSource[1] << smov);
				}
			}
			else {
				if (bc != 0)
				{
					u64 tmp = pSource[1] >> smov;
					if (bc + smov > 64)tmp |= pSource[2] << (64 - smov);
					*pEnd = (*pEnd&(((u64)-1) << bc)) | (tmp&(((u64)-1) >> (64 - bc)));
				}
				while (pDest != --pEnd)
				{
					*pEnd = (*pSource >> smov) | (*(pSource + 1) << (64 - smov));
					--pSource;
				}
			}
		}
		*pDest = (((*pSource >> sourceStartBitPositon) | (pSource[1] << (64 - sourceStartBitPositon))) << destStartBitPositon) | (*pDest&(((u64)-1) >> (64 - destStartBitPositon)));
	}
	void Bits::Move32(u32* pDest, s32 destStartBitPositon, cu32* pSource, s32 sourceStartBitPositon, u32 bitsCount)
	{
		if (bitsCount == 0)return;
		if (sourceStartBitPositon < 0) { pSource += (sourceStartBitPositon - 31) / 32; sourceStartBitPositon &= 31; }
		else if (sourceStartBitPositon >= 32) { pSource += sourceStartBitPositon / 32; sourceStartBitPositon &= 31; }
		if (destStartBitPositon < 0) { pDest += (destStartBitPositon - 31) / 32; destStartBitPositon &= 31; }
		else if (destStartBitPositon >= 32) { pDest += destStartBitPositon / 32; destStartBitPositon &= 31; }
		if (pDest <= pSource)
		{
			if (pDest < pSource || sourceStartBitPositon > destStartBitPositon) { Copy32(pDest, destStartBitPositon, pSource, sourceStartBitPositon, bitsCount); return; }
			if (sourceStartBitPositon == destStartBitPositon)return;
		}
		if (sourceStartBitPositon == 0)
		{
			if (destStartBitPositon == 0)
			{
				u32 bc = bitsCount & 31;
				u32 bm = bitsCount >> 5;
				u32* pEnd = bm + pDest;
				pSource += bm;
				if (bc != 0)*pEnd = (*pSource&(((u32)-1) >> (32 - bc))) | (*pEnd&(((u32)-1) << bc));
				while (pDest != pEnd)*--pEnd = *--pSource;
				return;
			}
			u32 bm = (destStartBitPositon + bitsCount) >> 5;
			u32* pEnd = bm + pDest;
			if (pEnd == pDest)
			{
				*pDest = (*pDest &(((((u32)-1) << (bitsCount + destStartBitPositon)) | (((u32)-1) >> (32 - destStartBitPositon)))))
					| ((*pSource&(((u32)-1) >> (32 - bitsCount))) << destStartBitPositon);
				return;
			}
			u32 bc = (destStartBitPositon + bitsCount) & 31;
			pSource += bm - 1;
			if (bc != 0)
			{
				u32 tmp = (*pSource >> (32 - destStartBitPositon));
				if (bc > (u32)destStartBitPositon)tmp |= pSource[1] << destStartBitPositon;
				*pEnd = (*pEnd&(((u32)-1) << bc)) | (tmp&(((u32)-1) >> (32 - bc)));
			}
			while (pDest != --pEnd) { --pSource; *pEnd = (*pSource >> (32 - destStartBitPositon)) | (*(pSource + 1) << destStartBitPositon); }
			*pDest = (*(pSource) << destStartBitPositon) | (*pDest&(((u32)-1) >> (32 - destStartBitPositon)));
			return;
		}
		if (destStartBitPositon == 0)
		{
			u32 bc = bitsCount & 31;
			u32 bm = bitsCount >> 5;
			u32* pEnd = bm + pDest;
			pSource += bm;
			if (bc != 0)
			{
				u32 tmp = *pSource >> sourceStartBitPositon;
				if (bc + sourceStartBitPositon > 32)tmp |= (pSource[1] << (32 - sourceStartBitPositon));
				*pEnd = (*pEnd & (((u32)-1) << bc)) | (tmp&(((u32)-1) >> (32 - bc)));
			}
			while (pEnd != pDest)
			{
				*--pEnd = (*(pSource - 1) >> sourceStartBitPositon) | (*pSource << (32 - sourceStartBitPositon));
				--pSource;
			}
			return;
		}
		u32 bm = (bitsCount + destStartBitPositon) >> 5;
		u32* pEnd = bm + pDest;
		if (pEnd == pDest)
		{
			u32 tmp = *pSource >> sourceStartBitPositon;
			if (bitsCount + sourceStartBitPositon > 32)tmp |= (pSource[1] << (32 - sourceStartBitPositon));
			*pDest = (*pDest &(((((u32)-1) << (bitsCount + destStartBitPositon)) | (((u32)-1) >> (32 - destStartBitPositon)))))
				| ((tmp&(((u32)-1) >> (32 - bitsCount))) << destStartBitPositon);
			return;
		}
		u32 bc = (bitsCount + destStartBitPositon) & 31;
		pSource += bm - 1;
		if (sourceStartBitPositon == destStartBitPositon)
		{
			if (bc != 0)
			{
				*pEnd = (*pEnd&(((u32)-1) << bc)) | ((*(pSource + 1))&(((u32)-1) >> (32 - bc)));
			}
			while (pDest != --pEnd) { *pEnd = *pSource--; }
		}
		else {
			s32 smov = sourceStartBitPositon - destStartBitPositon;
			if (smov < 0)
			{
				smov = -smov;
				if (bc != 0)
				{
					u32 tmp = *pSource >> (32 - smov);
					if (bc > (u32)smov)tmp |= pSource[1] << smov;
					*pEnd = (*pEnd&(((u32)-1) << bc)) | (tmp&(((u32)-1) >> (32 - bc)));
				}
				while (pDest != --pEnd)
				{
					--pSource;
					*pEnd = (*pSource >> (32 - smov)) | (pSource[1] << smov);
				}
			}
			else {
				if (bc != 0)
				{
					u32 tmp = pSource[1] >> smov;
					if (bc + smov > 32)tmp |= pSource[2] << (32 - smov);
					*pEnd = (*pEnd&(((u32)-1) << bc)) | (tmp&(((u32)-1) >> (32 - bc)));
				}
				while (pDest != --pEnd)
				{
					*pEnd = (*pSource >> smov) | (*(pSource + 1) << (32 - smov));
					--pSource;
				}
			}
		}
		*pDest = (((*pSource >> sourceStartBitPositon) | (pSource[1] << (32 - sourceStartBitPositon))) << destStartBitPositon) | (*pDest&(((u32)-1) >> (32 - destStartBitPositon)));
	}
	index_t Bits::Compare(void const* pa, index_t startBitPosition1, void const* pb, index_t startBitPosition2, size_t bitsCount)
	{
		if (bitsCount == 0)return 0;
		startBitPosition1 += ((size_t)pa&(sizeof(size_t) - 1)) * 8;
		size_t* p1 = (size_t*)(((size_t)pa)&(~(sizeof(size_t) - 1)));
		startBitPosition2 += ((size_t)pb&(sizeof(size_t) - 1)) * 8;
		size_t* p2 = (size_t*)(((size_t)pb)&(~(sizeof(size_t) - 1)));
		if (startBitPosition1 < 0) { p1 += (startBitPosition1 - (index_t)(sizeof(size_t) * 8 - 1)) / ((index_t)sizeof(size_t) * 8); startBitPosition1 &= (sizeof(size_t) * 8) - 1; }
		else if (startBitPosition1 >= (index_t)(sizeof(size_t) * 8)) { p1 += startBitPosition1 / ((index_t)sizeof(size_t) * 8); startBitPosition1 &= (sizeof(size_t) * 8) - 1; }
		if (startBitPosition2 < 0) { p2 += (startBitPosition2 - (index_t)(sizeof(size_t) * 8 - 1)) / ((index_t)sizeof(size_t) * 8); startBitPosition2 &= (sizeof(size_t) * 8) - 1; }
		else if (startBitPosition2 >= (index_t)(sizeof(size_t) * 8)) { p2 += startBitPosition2 / ((index_t)sizeof(size_t) * 8); startBitPosition2 &= (sizeof(size_t) * 8) - 1; }

		size_t bmv1 = bitsCount + startBitPosition1;
		size_t bmv2 = bitsCount + startBitPosition2;

		if (bitsCount <= sizeof(size_t) * 8)
		{
			size_t num1 = *(size_t*)p1 >> startBitPosition1;
			size_t num2 = *(size_t*)p2 >> startBitPosition2;
			if (startBitPosition1 + bitsCount > sizeof(size_t) * 8)num1 |= *((size_t*)p1 + 1) << ((sizeof(size_t) * 8) - startBitPosition1);
			if (startBitPosition2 + bitsCount > sizeof(size_t) * 8)num2 |= *((size_t*)p2 + 1) << ((sizeof(size_t) * 8) - startBitPosition2);
			if (bitsCount != (sizeof(size_t) * 8))
			{
				num1 &= ((size_t)-1) >> ((sizeof(size_t) * 8) - bitsCount);
				num2 &= ((size_t)-1) >> ((sizeof(size_t) * 8) - bitsCount);
			}
			return num1 > num2 ? 1 : num1 < num2 ? -1 : 0;
		}

		size_t bc1 = bmv1 & ((sizeof(size_t) * 8) - 1);
		size_t bc2 = bmv2 & ((sizeof(size_t) * 8) - 1);

		bmv1 /= sizeof(size_t) * 8;
		bmv2 /= sizeof(size_t) * 8;

		size_t* sp1 = (size_t*)p1 + bmv1;
		size_t* sp2 = (size_t*)p2 + bmv2;

		if (bc1 != 0)
		{
			size_t num1 = *sp1 << ((sizeof(size_t) * 8) - bc1);
			size_t num2 = bc2 == 0 ? 0 : *sp2 << ((sizeof(size_t) * 8) - bc2);
			if (bc1 >= bc2)num2 |= (*(sp2 - 1)) >> bc2;
			num2 &= ((size_t)-1) << ((sizeof(size_t) * 8) - bc1);
			if (num1 != num2)return num1 > num2 ? 1 : -1;
		}
		if (sp1 != p1) {
			if (bc1 > bc2)
			{
				size_t bc = bc1 - bc2;
				while (--sp1 != p1)
				{
					--sp2;
					size_t num1 = *sp1;
					size_t num2 = (*sp2 << bc) | (*(sp2 - 1) >> ((sizeof(size_t) * 8) - bc));
					if (num1 != num2)return num1 > num2 ? 1 : -1;
				}
			}
			else if (bc1 == bc2)
			{
				while (--sp1 != p1)
				{
					size_t num1 = *sp1;
					size_t num2 = *--sp2;
					if (num1 != num2)return num1 > num2 ? 1 : -1;
				}
			}
			else
			{
				size_t bc = bc2 - bc1;
				while (--sp1 != p1)
				{
					size_t num1 = *sp1;
					size_t num2 = (*sp2 << ((sizeof(size_t) * 8) - bc)) | (*(sp2 - 1) >> bc);
					if (num1 != num2)return num1 > num2 ? 1 : -1;
					--sp2;
				}
			}
		}
		size_t num1 = *(size_t*)p1 >> startBitPosition1;
		size_t num2 = *(size_t*)p2 >> startBitPosition2;
		if (startBitPosition2 != 0 && (startBitPosition1 == 0 || startBitPosition1 < startBitPosition2))num2 |= *((size_t*)p2 + 1) << ((sizeof(size_t) * 8) - startBitPosition2);
		num2 &= ((size_t)-1) >> startBitPosition1;
		return num1 > num2 ? 1 : num1 < num2 ? -1 : 0;
	}
	index_t Bits::DifferenceIndexHigh(void const *pa, index_t startBitPosition1, size_t bitCount1, void const*pb, index_t startBitPosition2, size_t bitCount2, index_t mov)
	{
		startBitPosition1 += ((size_t)pa&(sizeof(size_t) - 1)) * 8;
		size_t* p1 = (size_t*)((size_t)pa&(~(sizeof(size_t) - 1)));
		startBitPosition2 += ((size_t)pb&(sizeof(size_t) - 1)) * 8;
		size_t* p2 = (size_t*)((size_t)pb&(~(sizeof(size_t) - 1)));

		if (startBitPosition1 < 0) { (size_t*&)p1 += (startBitPosition1 - (index_t)(sizeof(size_t) * 8 - 1)) / ((index_t)sizeof(size_t) * 8); startBitPosition1 &= (sizeof(size_t) * 8) - 1; }
		else if (startBitPosition1 >= (index_t)(sizeof(size_t) * 8)) { (size_t*&)p1 += startBitPosition1 / ((index_t)sizeof(size_t) * 8); startBitPosition1 &= (sizeof(size_t) * 8) - 1; }
		if (startBitPosition2 < 0) { (size_t*&)p2 += (startBitPosition2 - (index_t)(sizeof(size_t) * 8 - 1)) / ((index_t)sizeof(size_t) * 8); startBitPosition2 &= (sizeof(size_t) * 8) - 1; }
		else if (startBitPosition2 >= (index_t)(sizeof(size_t) * 8)) { (size_t*&)p2 += startBitPosition2 / ((index_t)sizeof(size_t) * 8); startBitPosition2 &= (sizeof(size_t) * 8) - 1; }


		size_t abc1 = startBitPosition1 + bitCount1;
		size_t abc2 = startBitPosition2 + bitCount2;

		size_t* ps1 = (size_t*)p1 + (abc1 == 0 ? 0 : (abc1 - 1) / (sizeof(size_t) * 8));//指针
		size_t* ps2 = (size_t*)p2 + (abc2 == 0 ? 0 : (abc2 - 1) / (sizeof(size_t) * 8));

		size_t tbc1 = 0;//已读取比特数
		size_t tbc2 = 0;
		index_t state = 0;

		abc1 &= sizeof(size_t) * 8 - 1;//高位比特偏移
		abc2 &= sizeof(size_t) * 8 - 1;

		for (;;)
		{
			size_t num1;
			if (tbc1 >= bitCount1) { if (tbc2 >= bitCount2)break; num1 = 0; }
			else
			{
				if (mov >= ((index_t)sizeof(size_t) * 8)) { num1 = 0; }
				else
				{
					if (mov <= 0)
						num1 = abc1 == 0 ? *ps1 : ((*ps1 << (sizeof(size_t) * 8 - abc1)) | (*(ps1 - 1) >> abc1));
					else
					{
						if (abc1 == 0)
							num1 = tbc1 == 0 ? (*ps1 >> mov) : (*(ps1 + 1) << (sizeof(size_t) * 8 - mov)) | (*ps1 >> mov);
						else
						{
							if (tbc1 == 0)
								num1 = ((*ps1 << (sizeof(size_t) * 8 - abc1)) | (*(ps1 - 1) >> abc1)) >> mov;
							else
							{
								if (mov + abc1 > sizeof(size_t) * 8)num1 = (*(ps1 + 1) << (sizeof(size_t) * 16 - (abc1 + mov))) | (*ps1 >> (mov + abc1 - (sizeof(size_t) * 8)));
								else if (mov + abc1 == sizeof(size_t) * 8)num1 = *ps1;
								else num1 = (*ps1 << ((sizeof(size_t) * 8) - mov - abc1)) | (*(ps1 - 1) >> (abc1 + mov));
							}
						}
					}
					if (tbc1 == 0 && mov > 0)
					{
						if (tbc1 + sizeof(size_t) * 8 - mov > bitCount1)
							num1 &= ((size_t)-1) << (tbc1 - mov - bitCount1 + sizeof(size_t) * 8);
					}
					else if (tbc1 + sizeof(size_t) * 8 > bitCount1)
						num1 &= ((size_t)-1) << (tbc1 - bitCount1 + sizeof(size_t) * 8);
					--ps1;
				}
			}
			size_t num2;
			if (tbc2 >= bitCount2) { num2 = 0; }
			else
			{
				if (mov <= (-(index_t)sizeof(size_t) * 8)) { num2 = 0; }
				else
				{
					if (mov >= 0)
						num2 = abc2 == 0 ? *ps2 : ((*ps2 << (sizeof(size_t) * 8 - abc2)) | (*(ps2 - 1) >> abc2));
					else
					{
						if (abc2 == 0)
							num2 = tbc2 == 0 ? (*ps2 >> -mov) : (*(ps2 + 1) << (sizeof(size_t) * 8 + mov)) | (*ps2 >> -mov);
						else
						{
							if (tbc2 == 0)
								num2 = ((*ps2 << (sizeof(size_t) * 8 - abc2)) | (*(ps2 - 1) >> abc2)) >> -mov;
							else
							{
								if (abc2 - mov > sizeof(size_t) * 8)num2 = (*(ps2 + 1) << (sizeof(size_t) * 16 - (abc2 - mov))) | (*ps2 >> (abc2 - mov - (sizeof(size_t) * 8)));
								else if (abc2 - mov == sizeof(size_t) * 8)num2 = *ps2;
								else num2 = (*ps2 << ((sizeof(size_t) * 8) + mov - abc2)) | (*(ps2 - 1) >> (abc2 - mov));
							}
						}
					}
					if (tbc2 == 0 && mov<0)
					{
						if (tbc2 + sizeof(size_t) * 8 + mov> bitCount2)
							num2 &= ((size_t)-1) << (tbc2 + mov - bitCount2 + sizeof(size_t) * 8);
					}
					else if (tbc2 + sizeof(size_t) * 8 > bitCount2)
						num2 &= ((size_t)-1) << (tbc2 - bitCount2 + sizeof(size_t) * 8);
					--ps2;
				}
			}
			if (state == 0)
			{
				if (num1 != num2)
				{
					if (num1 > num2)
					{
						if (num1 != num2 + 1)
							return (tbc1 > tbc2 ? tbc1 : tbc2) + LeftZeroCount(num1 - num2) + 1;
						state = 1;
					}
					else
					{
						if (num2 != num1 + 1)
							return -(index_t)(tbc1 > tbc2 ? tbc1 : tbc2) - LeftZeroCount(num2 - num1) - 1;
						state = -1;
					}
				}
			}
			else if (state == 1)
			{
				if (num1 != 0 || num2 != (size_t)-1)
				{
					if (tbc1 < tbc2) tbc1 = tbc2;
					if (num1 < num2)return tbc1 + LeftZeroCount(num1 - num2) + 1;
					return tbc1;
				}
			}
			else  if (num2 != 0 || num1 != (size_t)-1)
			{
				if (tbc1 > tbc2) tbc2 = tbc1;
				if (num2 < num1)return -(index_t)tbc2 - LeftZeroCount(num2 - num1) - 1;
				return -(index_t)tbc2;
			}

			if (mov >= (index_t)sizeof(size_t) * 8)
			{
				mov -= sizeof(size_t) * 8;
				tbc2 += sizeof(size_t) * 8;
			}
			else if (mov <= -(index_t)sizeof(size_t) * 8)
			{
				mov += sizeof(size_t) * 8;
				tbc1 += sizeof(size_t) * 8;
			}
			else
			{
				if (mov > 0)
				{
					if (tbc1 == 0)tbc1 = -mov;
				}
				else if (mov < 0)
				{
					if (tbc2 == 0)tbc2 = mov;
				}
				tbc1 += sizeof(size_t) * 8;
				tbc2 += sizeof(size_t) * 8;
			}
		}
		if (state == 0)
			return 0;
		if (state == 1)return (tbc1>tbc2 ? tbc1 : tbc2);
		return -(index_t)(tbc1 > tbc2 ? tbc1 : tbc2);
	}
	void Bits::Shift(void *p, index_t startBitPosition, size_t bitsCount, index_t mov, bool mask)
	{
		if (bitsCount == 0 || mov == 0)return;
		if (mov >= (index_t)bitsCount || mov <= -(index_t)bitsCount) { Set(p, startBitPosition, bitsCount, mask); return; }
		if (mov > 0) {
			Move(p, startBitPosition + mov, p, startBitPosition, bitsCount - mov); Set(p, startBitPosition, mov, mask);
		}
		else {
			Copy(p, startBitPosition, p, startBitPosition - mov, bitsCount + mov); Set(p, startBitPosition + bitsCount + mov, -mov, mask);
		}
	}
	void Bits::Set(void* pp, index_t startBitPosition, size_t bitsCount, bool bitValue)//将p所指向的内存的startBitPosition比特起的bitsCount比特置为bit的值
	{
#ifdef _DEBUG
		if ((index_t)bitsCount < 0)throw - 1;
#endif
		if (bitsCount == 0)return;
		startBitPosition += ((size_t)pp&(sizeof(size_t) - 1)) * 8;
		size_t* p = (size_t*)((size_t)pp&(~(sizeof(size_t) - 1)));
		if (startBitPosition < 0) { p += (startBitPosition - (index_t)(sizeof(size_t) * 8 - 1)) / ((index_t)sizeof(size_t) * 8); startBitPosition &= (sizeof(size_t) * 8) - 1; }
		else if (startBitPosition >= (index_t)(sizeof(size_t) * 8)) { p += startBitPosition / ((index_t)sizeof(size_t) * 8); startBitPosition &= (sizeof(size_t) * 8) - 1; }

		size_t allBits = bitsCount + startBitPosition;
		if (allBits <= sizeof(size_t) * 8)
		{
			if (bitValue) { *p |= (((size_t)-1) >> ((sizeof(size_t) * 8) - bitsCount)) << startBitPosition; return; }
			*p &= ~((((size_t)-1) >> ((sizeof(size_t) * 8) - bitsCount)) << startBitPosition); return;
		}
		if (bitValue) { *p |= ((size_t)-1) << startBitPosition; }
		else *p &= ~(((size_t)-1) << startBitPosition);
		while (allBits > (sizeof(size_t) * 16))
		{
			allBits -= (sizeof(size_t) * 8);
			*++p = bitValue ? -1 : 0;
		}
		if (allBits == 0)return;
		if (bitValue) { *(p + 1) |= ((size_t)-1) >> ((sizeof(size_t) * 8) - allBits); }
		else *(p + 1) &= ~(((size_t)-1) >> ((sizeof(size_t) * 8) - allBits));
	}
	bool Bits::SelfPlusOne64(u64*p, u64 len, s64 mov)
	{
		u64 bm = 1ull << (mov & 63);
		if (mov < 0 || (mov /= 64) >= (index_t)len)return false;
		if (p[mov] >(~bm))
		{
			u64*pe = p + len;
			*(p += mov) += bm;
			while (++p != pe)if (++*p != 0)break;
			return p == pe;
		}
		p[mov] += bm;
		return false;
	}
	bool Bits::SelfPlusOneRound64(u64*p, u64 len, s64 mov)
	{
		u64 bm = 1ull << (mov & 63);
		if (mov < 0 || (mov /= 64) >= (index_t)len)
		{
			if (mov == -1)
			{
				u64*pe = p + len;
				while (p != pe&&++*p == 0)++p;
				return p == pe;
			}
			return false;
		}
		if (p[mov] >(~bm))
		{
			u64*pe = p + len;
			*(p += mov) += bm;
			while (++p != pe)if (++*p != 0)return false;
			return true;
		}
		p[mov] += bm;
		return false;
	}
	bool Bits::SelfPlusInt64(u64*p, u64 len, u64 num, s64 mov)
	{
		if (mov <= -64 || (mov / 64) >= (index_t)len)return false;
		u64*pe = p + len;
		if (mov<0)
		{
			mov &= 63;
			num >>= (64 - mov);
			if (*p > ~num)
			{
				*p += num;
				while (++p != pe)if (++*p != 0)return false;
				return true;
			}
			*p += num;
			return false;
		}
		p += mov / 64;
		if ((mov &= 63) == 0)
		{
			if (*p > ~num)
			{
				*p += num;
				while (++p != pe)if (++*p != 0)return false;
				return true;
			}
			*p += num;
			return false;
		}
		u64 lm = num << mov;
		num >>= 64 - mov;
		if (*p > (~lm)) { num++; (*p++) += lm; if (p == pe)return true; }
		else (*p++) += lm;
		if (p == pe)return false;
		if (*p > (~num))
		{
			*p += num;
			while (++p != pe)if (++*p != 0)return false;
			return true;
		}
		*p += num;
		return false;
	}
	bool Bits::SelfPlusIntRound64(u64*p, u64 len, u64 num, s64 mov)
	{
		if (mov >= 0 && (mov / 64) >= (index_t)len)return false;
		if (mov < -64)return false;
		u64*pe = p + len;
		if (mov == -64)
		{
			if ((s64)num < 0)
			{
				while (p != pe)if (++*p != 0)return false;
				return true;
			}
			return false;
		}
		if (mov<0)
		{
			mov = -mov;
			if (len == 0)return ((num >> (mov - 1)) & 1) != 0;
			num = (num >> mov) + ((num >> (mov - 1)) & 1);
			if (*p > ~num)
			{
				*p += num;
				while (++p != pe)if (++*p != 0)return false;
				return true;
			}
			*p += num;
			return false;
		}
		p += mov / 64;
		if ((mov &= 63) == 0)
		{
			if (*p > ~num)
			{
				*p += num;
				while (++p != pe)if (++*p != 0)return false;
				return true;
			}
			*p += num;
			return false;
		}
		u64 lm = num << mov;
		num >>= 64 - mov;
		if (*p > (~lm)) { num++; (*p++) += lm; if (p == pe)return true; }
		else (*p++) += lm;
		if (p == pe)return false;
		if (*p > (~num))
		{
			*p += num;
			while (++p != pe)if (++*p != 0)return false;
			return true;
		}
		*p += num;
		return false;
	}
	bool Bits::SelfPlus64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource, s64 mov)
	{
		size_t destStartIndex = (size_t)(mov < 64 ? 0 : (mov >> 6));
		mov = mov<0 ? -mov : -(mov & 63);
		bool flag = false;
		while (destStartIndex < lenDest)
		{
			u64 tmp = GetWindow64Low64(pSource, (size_t)lenSource, mov);
			if (flag)
			{
				flag = pDest[destStartIndex] >= ~tmp;
				pDest[destStartIndex] += tmp + 1;
			}
			else
			{
				flag = pDest[destStartIndex] > ~tmp;
				pDest[destStartIndex] += tmp;
			}
			mov += 64;
			if (tmp == 0 && flag == false && mov > (s64)lenSource * 64)return false;
			destStartIndex++;
		}
		return flag;
	}
	bool Bits::SelfPlusRound64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource, s64 mov)
	{
		size_t destStartIndex = (size_t)(mov < 64 ? 0 : (mov >> 6));
		bool flag = mov < 0 ? (s64)GetWindow64Low64(pSource, (size_t)lenSource, -64 - mov) < 0 : false;
		mov = mov<0 ? -mov : -(mov & 63);
		while (destStartIndex < lenDest)
		{
			u64 tmp = GetWindow64Low64(pSource, (size_t)lenSource, mov);
			if (flag)
			{
				flag = pDest[destStartIndex] >= ~tmp;
				pDest[destStartIndex] += tmp + 1;
			}
			else
			{
				flag = pDest[destStartIndex] > ~tmp;
				pDest[destStartIndex] += tmp;
			}
			mov += 64;
			if (tmp == 0 && flag == false && mov > (s64)lenSource * 64)return false;
			destStartIndex++;
		}
		return flag;
	}
	bool Bits::PlusOne64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource, s64 movSource, s64 mov)
	{
		movSource = -movSource;
		u64 ull = 1ull << (mov & 63);
		if (mov > 0)mov = mov / 64;
		bool flag = false;
		for (u64 i = 0; i < lenDest; ++i, movSource += 64)
		{
			u64 tmp = GetWindow64Low64(pSource, (size_t)lenSource, movSource);
			if (flag) {
				flag = (pDest[i] = ++tmp) == 0;
			}
			else if ((s64)i == mov) {
				flag = tmp > ~ull;
				pDest[i] = tmp + ull;
			}
			else pDest[i] = tmp;
		}
		return flag;
	}
	bool Bits::PlusOneRound64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource, s64 movSource, s64 mov)
	{
		movSource = -movSource;
		u64 tmp = GetWindow64Low64(pSource, (size_t)lenSource, movSource - 64);
		u64 ull = 1ull << (mov & 63);
		bool flag = (s64)tmp < 0;
		if (mov >= 0)
		{
			mov = mov / 64;
		}
		else if (mov >= -64)
		{
			flag = flag || (s64)(tmp + ull) < 0;
			mov = 0; ull = 0;
		}
		for (u64 i = 0; i < lenDest; ++i, movSource += 64)
		{
			tmp = GetWindow64Low64(pSource, (size_t)lenSource, movSource);
			if ((s64)i == mov)
			{
				if (flag) {
					flag = tmp >= ~ull;
					pDest[i] = tmp + ull + 1;
				}
				else {
					flag = tmp > ~ull;
					pDest[i] = tmp + ull;
				}
			}
			else
			{
				if (flag)flag = (pDest[i] = tmp + 1) == 0;
				else pDest[i] = tmp;
			}
		}
		return flag;
	}
	bool Bits::PlusInt64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource, u64 num, s64 movSource, s64 mov)
	{
		movSource = -movSource;
		u64 ull = num << (mov & 63);
		num = (mov & 63) == 0 ? 0 : num >> (64 - (mov & 63));
		if (mov >= 0)mov = mov / 64;
		else { mov = (mov - 63) / 64; }
		bool flag = false;
		for (u64 i = 0; i < lenDest; ++i, movSource += 64)
		{
			u64 tmp = GetWindow64Low64(pSource, (size_t)lenSource, movSource);
			u64 t;
			if ((s64)i == mov)t = ull;
			else if ((s64)i == mov + 1)t = num;
			else if (!flag) { pDest[i] = tmp; continue; }
			else t = 0;

			if (flag)
			{
				flag = tmp >= ~t;
				pDest[i] = tmp + t + 1;
			}
			else
			{
				flag = tmp > ~t;
				pDest[i] = tmp + t;
			}
		}
		return flag;
	}
	index_t Bits::PlusIntRound64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource, u64 num, s64 movSource, s64 mov)
	{
		movSource = -movSource;
		u64 tmp = GetWindow64Low64(pSource, (size_t)lenSource, movSource - 64);
		u64 ull = num << (mov & 63);
		num = (mov & 63) == 0 ? 0 : num >> (64 - (mov & 63));
		index_t flag = 0;
		if (mov >= 0)
		{
			mov = mov / 64;
			flag = (s64)tmp < 0;
		}
		else
		{
			if (mov >= -64)flag = (index_t)(tmp > ~ull) + ((s64)(tmp + ull) < 0);
			else if (mov > -128)flag = (index_t)(tmp > ~num) + ((s64)(tmp + num) < 0);
			else flag = (s64)tmp < 0;
			mov = (mov - 63) / 64;
		}

		for (u64 i = 0; i < lenDest; ++i, movSource += 64)
		{
			tmp = GetWindow64Low64(pSource, (size_t)lenSource, movSource);
			u64 t = (s64)i == mov ? ull : (s64)i == mov + 1 ? num : 0;
			if (flag != 0) {
				if (flag == 2)
				{
					flag = (s64)tmp != -1ll ? tmp + 1 >= ~t : 1;
					pDest[i] = tmp + t + 2;
				}
				else
				{
					flag = tmp >= ~t;
					pDest[i] = tmp + t + 1;
				}
			}
			else
			{
				flag = tmp > ~t;
				pDest[i] = tmp + t;
			}
		}
		return flag;
	}
	bool Bits::Plus64(u64*pDest, u64 lenDest, cu64*p1, u64 len1, cu64*p2, u64 len2, s64 mov1, s64 mov2)
	{
		mov1 = -mov1;
		mov2 = -mov2;
		bool flag = false;
		for (size_t i = 0; i < lenDest; ++i)
		{
			u64 tmp1 = GetWindow64Low64(p1, (size_t)len1, mov1);
			u64 tmp2 = GetWindow64Low64(p2, (size_t)len2, mov2);
			if (flag)
			{
				flag = tmp1 >= ~tmp2;
				pDest[i] = tmp1 + tmp2 + 1;
			}
			else
			{
				flag = tmp1 > ~tmp2;
				pDest[i] = tmp1 + tmp2;
			}
			mov1 += 64;
			mov2 += 64;
		}
		return flag;
	}
	index_t Bits::PlusRound64(u64*pDest, u64 lenDest, cu64*p1, u64 len1, cu64*p2, u64 len2, s64 mov1, s64 mov2)
	{
		mov1 = -mov1;
		mov2 = -mov2;
		u64 tmp1 = GetWindow64Low64(p1, (size_t)len1, mov1 - 64);
		u64 tmp2 = GetWindow64Low64(p2, (size_t)len2, mov2 - 64);
		index_t flag = (index_t)(tmp1 > ~tmp2) + ((s64)(tmp1 + tmp2) < 0);

		for (size_t i = 0; i < lenDest; ++i)
		{
			tmp1 = GetWindow64Low64(p1, (size_t)len1, mov1);
			tmp2 = GetWindow64Low64(p2, (size_t)len2, mov2);
			if (flag != 0)
			{
				if (flag == 2)
				{
					flag = tmp1 == (u64)-1 && tmp2 == (u64)-1 ? 2 :
						(s64)tmp1 != -1ll ? tmp1 + 1 >= ~tmp2 : 1;
					pDest[i] = tmp1 + tmp2 + 2;
				}
				else
				{
					flag = tmp1 >= ~tmp2;
					pDest[i] = tmp1 + tmp2 + 1;
				}
			}
			else
			{
				flag = tmp1 > ~tmp2;
				pDest[i] = tmp1 + tmp2;
			}
			mov1 += 64;
			mov2 += 64;
		}
		return flag;
	}
	bool Bits::SelfMinusInt64(u64*p, u64 len, u64 num, s64 mov)
	{
		if (mov <= -64 || (mov / 64) >= (s64)len)return false;
		u64*pe = p + len;
		if (mov < 0)
		{
			mov &= 63;
			num >>= (64 - mov);
			if (*p < num)
			{
				*p -= num;
				while (++p != pe)if ((*p)-- != 0)return false;
				return true;
			}
			*p -= num;
			return false;
		}
		p += mov / 64;
		if ((mov &= 63) == 0)
		{
			if (*p < num)
			{
				*p -= num;
				while (++p != pe)if ((*p)-- != 0)return false;
				return true;
			}
			*p -= num;
			return false;
		}
		u64 lm = num << mov;
		num >>= 64 - mov;
		if (*p < lm) { num++; (*p++) -= lm; if (p == pe)return true; }
		else (*p++) -= lm;
		if (p == pe)return false;
		if (*p < num)
		{
			*p -= num;
			while (++p != pe)if ((*p)-- != 0)return false;
			return true;
		}
		*p -= num;
		return false;
	}
	bool Bits::SelfMinusIntRound64(u64*p, u64 len, u64 num, s64 mov)
	{
		if (mov >= 0 && (mov / 64) >= (s64)len)return false;
		if (mov < -64)return false;
		u64*pe = p + len;
		if (mov < 0)
		{
			mov &= 63;
			if (p == pe)return (-(s64)(num << (mov))>0);
			num = (mov == 0) ? (-(s64)num>0) : ((num >> (64 - mov)) + (-(s64)(num << (mov))>0));
			if (*p < num)
			{
				*p -= num;
				while (++p != pe)if ((*p)-- != 0)return false;
				return true;
			}
			*p -= num;
			return false;
		}
		p += mov / 64;
		if ((mov &= 63) == 0)
		{
			if (*p < num)
			{
				*p -= num;
				while (++p != pe)if ((*p)-- != 0)return false;
				return true;
			}
			*p -= num;
			return false;
		}
		u64 lm = num << mov;
		num >>= 64 - mov;
		if (*p < lm) { num++; (*p++) -= lm; if (p == pe)return true; }
		else (*p++) -= lm;
		if (p == pe)return false;
		if (*p < num)
		{
			*p -= num;
			while (++p != pe)if ((*p)-- != 0)return false;
			return true;
		}
		*p -= num;
		return false;
	}
	bool Bits::SelfMinus64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource, s64 mov)
	{
		size_t destStartIndex = (size_t)(mov < 64 ? 0 : (mov >> 6));
		mov = mov < 0 ? -mov : -(mov & 63);
		bool flag = false;
		while (destStartIndex < lenDest)
		{
			u64 tmp = GetWindow64Low64(pSource, (size_t)lenSource, mov);
			if (flag)
			{
				flag = pDest[destStartIndex] <= tmp;
				pDest[destStartIndex] -= tmp + 1;
			}
			else
			{
				flag = pDest[destStartIndex] <tmp;
				pDest[destStartIndex] -= tmp;
			}
			mov += 64;
			if (tmp == 0 && flag == false && mov > (s64)lenSource * 64)return false;
			destStartIndex++;
		}
		return flag;
	}
	bool Bits::SelfMinus64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource)
	{
		bool flag = false;
		for (size_t destStartIndex = 0; destStartIndex < lenDest; destStartIndex++)
		{
			u64 tmp = destStartIndex < lenSource ? pSource[destStartIndex] : 0;
			if (flag)
			{
				flag = pDest[destStartIndex] <= tmp;
				pDest[destStartIndex] -= tmp + 1;
			}
			else
			{
				flag = pDest[destStartIndex] < tmp;
				pDest[destStartIndex] -= tmp;
			}
			if (tmp == 0 && flag == false && destStartIndex >= lenSource)return false;
		}
		return flag;
	}
	bool Bits::SelfMinusRound64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource, s64 mov)
	{
		size_t destStartIndex = (size_t)(mov < 64 ? 0 : (mov >> 6));
		bool flag = mov < 0 ? (-(s64)GetWindow64Low64(pSource, (size_t)lenSource, -64 - mov))>0 : false;
		mov = mov < 0 ? -mov : -(mov & 63);
		while (destStartIndex < lenDest)
		{
			u64 tmp = GetWindow64Low64(pSource, (size_t)lenSource, mov);
			if (flag)
			{
				flag = pDest[destStartIndex] <= tmp;
				pDest[destStartIndex] -= tmp + 1;
			}
			else
			{
				flag = pDest[destStartIndex] <tmp;
				pDest[destStartIndex] -= tmp;
			}
			mov += 64;
			if (tmp == 0 && flag == false && mov > (s64)lenSource * 64)return false;
			destStartIndex++;
		}
		return flag;
	}
	bool Bits::MinusOne64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource, s64 movSource, s64 mov)
	{
		movSource = -movSource;
		u64 ull = 1ull << (mov & 63);
		if (mov > 0)mov = mov / 64;
		bool flag = false;
		for (u64 i = 0; i < lenDest; ++i, movSource += 64)
		{
			u64 tmp = GetWindow64Low64(pSource, (size_t)lenSource, movSource);
			if (flag) {
				flag = (pDest[i] = tmp)-- == 0;
			}
			else if ((s64)i == mov) {
				flag = tmp < ull;
				pDest[i] = tmp - ull;
			}
			else pDest[i] = tmp;
		}
		return flag;
	}
	index_t Bits::MinusOneRound64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource, s64 movSource, s64 mov)
	{
		movSource = -movSource;
		u64 ull = 1ull << (mov & 63);
		index_t flag = 0;
		if (mov >= 0) { mov = mov / 64; flag = (s64)GetWindow64Low64(pSource, (size_t)lenSource, movSource - 64) < 0; }
		else if (mov >= -64)
		{
			u64 tmp = GetWindow64Low64(pSource, (size_t)lenSource, movSource - 64);
			if (tmp >= ull)flag = (s64)(tmp - ull) < 0;
			else flag = (s64)(tmp - ull) > 0 ? -1 : 0;
		}
		else flag = (s64)GetWindow64Low64(pSource, (size_t)lenSource, movSource - 64) < 0;
		for (u64 i = 0; i < lenDest; ++i, movSource += 64)
		{
			u64 tmp = GetWindow64Low64(pSource, (size_t)lenSource, movSource);
			if ((s64)i == mov)
			{
				if (flag > 0)ull -= 1;
				flag = tmp < ull ? -1 : 0;
				pDest[i] = tmp - ull;
			}
			else if (flag != 0)
			{
				if (flag > 0)flag = (pDest[i] = tmp + 1) == 0;
				else flag = (pDest[i] = tmp)-- == 0 ? -1 : 0;
			}
			else pDest[i] = tmp;
		}
		return flag;
	}
	bool Bits::MinusInt64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource, u64 num, s64 movSource, s64 mov)
	{
		movSource = -movSource;
		u64 ull = num << (mov & 63);
		num = (mov & 63) == 0 ? 0 : num >> (64 - (mov & 63));
		if (mov >= 0)mov = mov / 64;
		else { mov = (mov - 63) / 64; }
		bool flag = false;
		for (u64 i = 0; i < lenDest; ++i, movSource += 64)
		{
			u64 tmp = GetWindow64Low64(pSource, (size_t)lenSource, movSource);
			u64 t;
			if ((s64)i == mov)t = ull;
			else if ((s64)i == mov + 1)t = num;
			else if (!flag) { pDest[i] = tmp; continue; }
			else t = 0;
			if (flag)
			{
				flag = tmp <= t;
				pDest[i] = tmp - t - 1;
			}
			else
			{
				flag = tmp < t;
				pDest[i] = tmp - t;
			}
		}
		return flag;
	}
	index_t Bits::MinusIntRound64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource, u64 num, s64 movSource, s64 mov)
	{
		movSource = -movSource;
		u64 tmp = GetWindow64Low64(pSource, (size_t)lenSource, movSource - 64);
		u64 ull = num << (mov & 63);
		num = (mov & 63) == 0 ? 0 : num >> (64 - (mov & 63));
		index_t flag = 0;
		if (mov >= 0)
		{
			mov = mov / 64;
			flag = (s64)tmp < 0;
		}
		else
		{
			if (mov >= -64)
			{
				if (tmp >= ull)flag = (s64)(tmp - ull) < 0;
				else flag = (s64)(tmp - ull) > 0 ? -1 : 0;
			}
			else if (mov > -128)
			{
				if (tmp >= num)flag = (s64)(tmp - num) < 0;
				else flag = (s64)(tmp - num) > 0 ? -1 : 0;
			}
			else flag = (s64)tmp < 0;
			mov = (mov - 63) / 64;
		}

		for (u64 i = 0; i < lenDest; ++i, movSource += 64)
		{
			tmp = GetWindow64Low64(pSource, (size_t)lenSource, movSource);
			if ((s64)i == mov)
			{
				if (ull != 0)
				{
					if (flag > 0)ull -= 1;
					flag = tmp < ull ? -1 : 0;
					pDest[i] = tmp - ull;
				}
				else if (flag > 0) flag = (pDest[i] = tmp + 1) == 0;
				else pDest[i] = tmp;
			}
			else if ((s64)i == mov + 1)
			{
				if (num != 0)
				{
					if (flag != 0)num -= flag;
					flag = tmp < num ? -1 : 0;
					pDest[i] = tmp - num;
				}
				else if (flag != 0)
				{
					if (flag > 0)flag = (pDest[i] = tmp + 1) == 0;
					else flag = (s64)(pDest[i] = tmp - 1) == -1 ? -1 : 0;
				}
				else pDest[i] = tmp;
			}
			else if (flag != 0)
			{
				if (flag > 0)flag = (pDest[i] = tmp + 1) == 0;
				else flag = (s64)(pDest[i] = tmp - 1) == -1 ? -1 : 0;
			}
			else pDest[i] = tmp;
		}
		return flag;
	}
	bool Bits::Minus64(u64*pDest, u64 lenDest, cu64*p1, u64 len1, cu64*p2, u64 len2, s64 mov1, s64 mov2)
	{
		mov1 = -mov1;
		mov2 = -mov2;
		bool flag = false;
		for (size_t i = 0; i < lenDest; ++i)
		{
			u64 tmp1 = GetWindow64Low64(p1, (size_t)len1, mov1);
			u64 tmp2 = GetWindow64Low64(p2, (size_t)len2, mov2);
			if (flag)
			{
				flag = tmp1 <= tmp2;
				pDest[i] = tmp1 - tmp2 - 1;
			}
			else
			{
				flag = tmp1 < tmp2;
				pDest[i] = tmp1 - tmp2;
			}
			mov1 += 64;
			mov2 += 64;
		}
		return flag;
	}
	index_t Bits::MinusRound64(u64*pDest, u64 lenDest, cu64*p1, u64 len1, cu64*p2, u64 len2, s64 mov1, s64 mov2)
	{
		mov1 = -mov1;
		mov2 = -mov2;
		u64 tmp1 = GetWindow64Low64(p1, (size_t)len1, mov1 - 64);
		u64 tmp2 = GetWindow64Low64(p2, (size_t)len2, mov2 - 64);
		index_t flag = tmp1 >= tmp2 ? (s64)(tmp1 - tmp2) < 0 : ((s64)(tmp1 - tmp2) > 0 ? -1 : 0);
		for (size_t i = 0; i < lenDest; ++i)
		{
			tmp1 = GetWindow64Low64(p1, (size_t)len1, mov1);
			tmp2 = GetWindow64Low64(p2, (size_t)len2, mov2);
			if (flag != 0)
			{
				if (flag < 0)
				{
					flag = tmp1 <= tmp2 ? -1 : 0;
					pDest[i] = tmp1 - tmp2 - 1;
				}
				else
				{
					flag = tmp2 == 0 ? (s64)tmp1 == -1 : tmp1 < tmp2 - 1 ? -1 : 0;
					pDest[i] = tmp1 - tmp2 + 1;
				}
			}
			else
			{
				flag = tmp1 < tmp2 ? -1 : 0;
				pDest[i] = tmp1 - tmp2;
			}
			mov1 += 64;
			mov2 += 64;
		}
		return flag;
	}
	bool Bits::SelfLimitBitsRoundHigh64(u64* p, u64 len, s64 mov)
	{
		if (mov > 0) { for (size_t i = 0; i < len; ++i)p[i] = 0; return false; }
		mov = len * 64 + mov;
		if (mov <= 0)return false;
		size_t i = (size_t)(mov / 64);
		mov &= 63;
		u64 ull = mov == 0 ? ((s64)p[i - 1] < 0) : ((p[i] & (1ull << (mov - 1))) << 1);
		for (size_t k = 0; k < i; ++k)p[k] = 0;
		if (mov != 0)p[i] = (p[i] >> mov) << mov;
		while (i < len)
		{
			if (ull != 0)
				ull = (p[i] += ull) == 0;
			else return false;
			++i;
		}
		return ull != 0;
	}
	u32 Bits::SelfMultiplyInt32Low32(u32*p, size_t len, u32 num)
	{
		u64 tmp = 0;
		for (size_t i = 0; i < len; ++i)
		{
			tmp += (u64)p[i] * (u64)num;
			p[i] = (u32)tmp;
			tmp >>= 32;
		}
		return (u32)tmp;
	}
	u64 Bits::SelfMultiplyInt64Low32(u32*p, size_t len, u64 num)
	{
		u64 tmp[2] = { 0 };
		u64 ull = num >> 32;
		num &= (u32)-1;
		for (size_t i = 0; i < len; ++i)
		{
			u64 t = (u64)p[i] * num;
			if (tmp[0] > ~t)tmp[1]++;
			tmp[0] += t;
			*(u64*)((u32*)tmp + 1) += (u64)p[i] * ull;
			p[i] = (u32)tmp[0];
			tmp[0] = (tmp[0] >> 32) | (tmp[1] << 32);
			tmp[1] >>= 32;
		}
		return tmp[0];
	}
	u64 Bits::SelfMultiplyInt64Low64(u64*p, size_t len, u64 num)
	{
		u64 tmp[2];
		tmp[0] = 0;
		for (size_t i = 0; i < len; ++i)
		{
			u64 t = Multiply(p[i], num, tmp + 1);
			if (tmp[0] > ~t)tmp[1]++;
			p[i] = tmp[0] + t;
			tmp[0] = tmp[1];
		}
		return tmp[0];
	}
	u32 Bits::SelfMultiplyInt32High32(u32*p, size_t len, u32 num)
	{
		if (len == 0)return 0;
		u64 t = num*(u64)p[0];
		u64 tmp = t >> 32;
		for (size_t i = 0; i < len - 1; ++i)
		{
			tmp += (u64)p[i + 1] * (u64)num;
			p[i] = (u32)tmp;
			tmp >>= 32;
		}
		p[len - 1] = (u32)tmp;
		return (u32)t;
	}
	u64 Bits::SelfMultiplyInt64High32(u32*p, size_t len, u64 num)
	{
		if (len == 0)return 0;
		u64 tmp[2] = { 0 };
		u64 ull = num >> 32;
		num &= (u32)-1;
		u64 result = 0;
		for (size_t i = 0; i < len; ++i)
		{
			u64 t = (u64)p[i] * num;
			if (tmp[0] > ~t)tmp[1]++;
			tmp[0] += t;
			*(u64*)((u32*)tmp + 1) += (u64)p[i] * ull;
			if (i < 2) ((u32*)&result)[i] = (u32)tmp[0];
			else p[i - 2] = (u32)tmp[0];
			tmp[0] = (tmp[0] >> 32) | (tmp[1] << 32);
			tmp[1] = 0;
		}
		if (len == 1)
		{
			p[0] = tmp[0] >> 32;
			result |= tmp[0] << 32;
		}
		else
		{
			*(u64*)(p + len - 2) = *tmp;
		}
		return result;
	}
	u64 Bits::SelfMultiplyInt64High64(u64*p, size_t len, u64 num)
	{
		if (len == 0)return 0;
		u64 tlow, thigh;
		u64 t = Multiply(p[0], num, &tlow);
		for (size_t i = 0; i < len - 1; ++i)
		{
			u64 ull = Multiply(p[i + 1], num, &thigh);
			if (tlow > ~ull)++thigh;
			p[i] = tlow + ull;
			tlow = thigh;
		}
		p[len - 1] = tlow;
		return t;
	}
	u32 Bits::MultiplyInt32Low32(u32 *pDest, size_t lenDest, cu32*pSource, size_t lenSource, u32 num)
	{
		u64 tmp = 0;
		for (size_t i = 0; i <(lenSource>lenDest ? lenDest : lenSource); ++i)
		{
			tmp += (u64)pSource[i] * (u64)num;
			pDest[i] = (u32)tmp;
			tmp >>= 32;
		}
		if (lenSource<lenDest)
		{
			pDest[lenSource] = (u32)tmp;
			while (++lenSource != lenDest)pDest[lenSource] = 0;
			return 0;
		}
		return (u32)(lenSource == lenDest ? tmp : (pSource[lenDest] * num + tmp));
	}
	u64 Bits::MultiplyInt64Low32(u32 *pDest, size_t lenDest, cu32*pSource, size_t lenSource, u64 num)
	{
		u64 tmp[2] = { 0 };
		u64 thigh = num >> 32;
		u64 tlow = num & (u32)-1;
		for (size_t i = 0; i < (lenSource>lenDest ? lenDest : lenSource); ++i)
		{
			u64 t = pSource[i] * tlow;
			if (tmp[0]>~t)tmp[1]++;
			tmp[0] += t;
			*(u64*)((u32*)tmp + 1) += pSource[i] * thigh;
			pDest[i] = (u32)tmp[0];
			tmp[0] = (tmp[0] >> 32) | (tmp[1] << 32);
			tmp[1] >>= 32;
		}
		if (lenSource < lenDest)
		{
			pDest[lenSource] = (u32)tmp[0];
			if (++lenSource != lenDest) { pDest[lenSource] = (tmp[0] >> 32); tmp[0] = 0; }
			else return tmp[0] >> 32;
			while (++lenSource != lenDest)pDest[lenSource] = 0;
			return 0;
		}
		return lenSource == lenDest ? tmp[0] :
			(lenSource == lenDest + 1) ? (pSource[lenDest] * num + tmp[0]) :
			((*(u64*)(pSource + lenDest))*num + tmp[0]);
	}
	u64 Bits::MultiplyInt64Low64(u64 *pDest, size_t lenDest, cu64*pSource, size_t lenSource, u64 num)
	{
		u64 tlow = 0, thigh;
		for (size_t i = 0; i <(lenSource>lenDest ? lenDest : lenSource); ++i)
		{
			u64 t = Multiply(pSource[i], num, &thigh);
			if (tlow > ~t)++thigh;
			pDest[i] = tlow + t;
			tlow = thigh;
		}
		if (lenSource < lenDest)
		{
			pDest[lenSource] = tlow;
			while (++lenSource != lenDest)pDest[lenSource] = 0;
			return 0;
		}
		return lenSource == lenDest ? tlow : (pSource[lenDest] * num + tlow);
	}
	u32 Bits::MultiplyInt32High32(u32*pDest, size_t lenDest, cu32*pSource, size_t lenSource, u32 num)
	{
		u64 t;
		u64 tmp;
		if (lenDest > lenSource)
		{
			//当lenDest多于容纳结果所需大小时（lenDest>lenSource+1），进行数据置零
			while (lenDest > lenSource + 1)
			{
				*pDest++ = 0;
				--lenDest;
			}
			//若刚刚好能容纳所需大小，则什么都不用做lenDest==lenSource+1
			t = 0;
			tmp = 0;
		}
		else//lenDest<=lenSource
		{
			//若空间不足，则应该适当调整源数据大小lenDest+1<=lenSource
			if (lenDest < lenSource)
			{
				pSource += lenSource - lenDest - 1;
				lenSource = lenDest + 1;
				tmp = (((u64)*pSource)*num) >> 32;
				if (lenSource == 1)return (u32)tmp;
				t = (((u64)pSource[1])*num) + tmp;
				tmp = t >> 32;
				lenSource -= 2;
				pSource += 2;
			}
			else//lenSource==lenDest
			{
				if (lenSource == 0)return 0;
				t = (((u64)*pSource)*num);
				tmp = t >> 32;
				lenSource--;
				pSource++;
			}
		}
		for (size_t i = 0; i < lenSource; ++i)//需要lenDest==lenSource+1
		{
			tmp += (u64)pSource[i] * (u64)num;
			pDest[i] = (u32)tmp;
			tmp >>= 32;
		}
		if (lenDest != 0)pDest[lenSource] = (u32)tmp;
		return (u32)t;
	}
	u64 Bits::MultiplyInt64High64(u64*pDest, size_t lenDest, cu64*pSource, size_t lenSource, u64 num)
	{
		u64 t;
		u64 tlow, thigh;
		if (lenDest > lenSource)
		{
			//当lenDest多于容纳结果所需大小时（lenDest>lenSource+1），进行数据置零
			while (lenDest > lenSource + 1)
			{
				*pDest++ = 0;
				--lenDest;
			}
			//若刚刚好能容纳所需大小，则什么都不用做lenDest==lenSource+1
			t = 0;
			tlow = 0;
		}
		else//lenDest<=lenSource
		{
			//若空间不足，则应该适当调整源数据大小lenDest+1<=lenSource
			if (lenDest < lenSource)
			{
				pSource += lenSource - lenDest - 1;
				lenSource = lenDest + 1;
				Multiply(*pSource, num, &tlow);
				if (lenSource == 1)return tlow;
				t = Multiply(pSource[1], num, &thigh);
				if (t > ~tlow)++thigh;
				t += tlow;
				tlow = thigh;
				lenSource -= 2;
				pSource += 2;
			}
			else//lenSource==lenDest
			{
				if (lenSource == 0)return 0;
				t = Multiply(*pSource, num, &tlow);
				lenSource--;
				pSource++;
			}
		}
		for (size_t i = 0; i < lenSource; ++i)//需要lenDest==lenSource+1
		{
			u64 tmp = Multiply(pSource[i], num, &thigh);
			if (tlow > ~tmp)++thigh;
			pDest[i] = tlow + tmp;
			tlow = thigh;
		}
		if (lenDest != 0)pDest[lenSource] = tlow;
		return t;
	}
	u32 Bits::MultiplyLow32(u32*pDest, size_t lenDest, cu32* pm1, size_t len1, cu32*pm2, size_t len2)
	{
		u64 tlow = 0, thigh = 0;
		if (len1 == 0 || len2 == 0) { memset(pDest, 0, lenDest*sizeof(u32)); return 0; }
		size_t len = len1 + len2;
		size_t i = 0;
		for (;; ++i)
		{
			//当i>=len1+len2时，乘积结果为0
			if (i >= len) { if (i == lenDest)break; pDest[i] = 0; continue; }
			//当i<len1+len2时，要收集所有x+y==i，x∈[0,len1-1]，y∈[0,len2-1]的x,y对应的pm1[x]*pm2[y]乘积求和
			for (size_t x = (i < len2 ? 0 : i - len2 + 1); x < len1; ++x)
			{
				size_t y = i - x;
				u64 tmp = (u64)pm1[x] * pm2[y];
				if (tlow > ~tmp)++thigh;
				tlow += tmp;
				if (y == 0)break;
			}
			if (i == lenDest)return (u32)tlow;
			pDest[i] = (u32)tlow;
			tlow = (thigh << 32) | (tlow >> 32);
			thigh >>= 32;
		}
		return 0;
	}
	u64 Bits::MultiplyLow64(u64*pDest, size_t lenDest, cu64* pm1, size_t len1, cu64*pm2, size_t len2)
	{
		u64 tl = 0, th = 0, thigh = 0;
		if (len1 == 0 || len2 == 0) { memset(pDest, 0, lenDest*sizeof(u64)); return 0; }
		size_t len = len1 + len2;
		size_t i = 0;
		for (;; ++i)
		{
			//当i>=len1+len2时，乘积结果为0
			if (i >= len) { if (i == lenDest)break; pDest[i] = 0; continue; }
			//当i<len1+len2时，要收集所有x+y==i，x∈[0,len1-1]，y∈[0,len2-1]的x,y对应的pm1[x]*pm2[y]乘积求和
			for (size_t x = (i < len2 ? 0 : i - len2 + 1); x < len1; ++x)
			{
				size_t y = i - x;
				u64 tmphigh;
				u64 tmplow = Multiply(pm1[x], pm2[y], &tmphigh);
				if (tl > ~tmplow)if (++th == 0)++thigh;
				tl += tmplow;
				if (th > ~tmphigh)++thigh;
				th += tmphigh;
				if (y == 0)break;
			}
			if (i == lenDest)return tl;
			pDest[i] = tl;
			tl = th;
			th = thigh;
			thigh = 0;
		}
		return 0;
	}
	u32 Bits::MultiplyHigh32(u32*pDest, size_t lenDest, cu32* pm1, size_t len1, cu32*pm2, size_t len2)
	{
		if (len1 == 0 || len2 == 0) { memset(pDest, 0, lenDest*sizeof(u32)); return 0; }
		u64 tlow = 0, thigh = 0;
		u32 ret = 0;
		//乘数乘积长度
		size_t sumlen = len1 + len2;
		//如果目标内存足够，则多余部分置0
		while (lenDest > sumlen)
		{
			*pDest++ = 0;
			lenDest--;
		}
		//sum起始值设定,pDest[lenDest-1]对应pm1[len1-1]*pm2[len2-1]右移32位的结果，因此其对应的系数和应该是len1+len2-1
		size_t sum = sumlen - lenDest;
		//返回值对应的sum,如果sum=0，那么sumrt将是-1，将永远取不到
		size_t sumrt = sum - 1;
		//开始循环求和
		for (size_t i = sum < 2 ? 0 : sum - 2; i < sumlen; ++i)
		{
			//x+y=i , x∈[0,len1-1] , y∈[0,len2-1]
			for (size_t x = (i < len2 ? 0 : i - len2 + 1); x < len1; ++x)
			{
				size_t y = i - x;
				u64 tmp = (u64)pm1[x] * pm2[y];
				if (tlow > ~tmp)++thigh;
				tlow += tmp;
				if (y == 0)break;
			}
			if (i >= sum)pDest[i - sum] = (u32)tlow;
			else if (i == sumrt) { ret = (u32)tlow; }
			tlow = (thigh << 32) | (tlow >> 32);
			thigh >>= 32;
		}
		return ret;
	}
	u64 Bits::MultiplyHigh64(u64*pDest, size_t lenDest, cu64* pm1, size_t len1, cu64*pm2, size_t len2)
	{
		if (len1 == 0 || len2 == 0) { memset(pDest, 0, lenDest*sizeof(u64)); return 0; }
		u64 tl = 0, th = 0, thigh = 0;
		u64 ret = 0;
		//乘数乘积长度
		size_t sumlen = len1 + len2;
		//如果目标内存足够，则多余部分置0
		while (lenDest > sumlen)
		{
			*pDest++ = 0;
			lenDest--;
		}
		//sum起始值设定,pDest[lenDest-1]对应pm1[len1-1]*pm2[len2-1]右移32位的结果，因此其对应的系数和应该是len1+len2-1
		size_t sum = sumlen - lenDest;
		//返回值对应的sum,如果sum=0，那么sumrt将是-1，将永远取不到
		size_t sumrt = sum - 1;
		//开始循环求和
		for (size_t i = sum < 2 ? 0 : sum - 2; i < sumlen; ++i)
		{
			//x+y=i , x∈[0,len1-1] , y∈[0,len2-1]
			for (size_t x = (i < len2 ? 0 : i - len2 + 1); x < len1; ++x)
			{
				size_t y = i - x;
				u64 tmphigh;
				u64 tmplow = Multiply(pm1[x], pm2[y], &tmphigh);
				if (tl > ~tmplow)if (++th == 0)++thigh;
				tl += tmplow;
				if (th > ~tmphigh)++thigh;
				th += tmphigh;
				if (y == 0)break;
			}
			if (i >= sum)pDest[i - sum] = tl;
			else if (i == sumrt) { ret = tl; }
			tl = th;
			th = thigh;
			thigh = 0;
		}
		return ret;
	}
#ifdef LK_MATH_DOUBLECOMPLEX_
	u8 Bits::MultiplyFFTLow8(u8*pDest, size_t lenDest, cu8* pm1, size_t len1, cu8*pm2, size_t len2)
	{
		if (len1 == 0 || len2 == 0) { memset(pDest, 0, lenDest*sizeof(u16)); return 0; }
		size_t len = ((size_t)1) << (sizeof(size_t) * 8 + 1 - LeftZeroCount((len1 > len2 ? len1 : len2) - 1));
		unsigned char* arr;
		size_t mask = Memory::GetBuffer(sizeof(Math::DoubleComplex)*len * 2, &arr);
		Math::DoubleComplex* dc1 = (Math::DoubleComplex*)(unsigned char*)arr;
		Math::DoubleComplex* dc2 = dc1 + len;
		Math::DoubleComplex::FFTLow8(pm1, dc1, len1, len);
		Math::DoubleComplex::FFTLow8(pm2, dc2, len2, len);
		for (size_t i = 0; i < len; ++i) { dc1[i] *= dc2[i]; }
		u8 result = Math::DoubleComplex::IFFTLow8(dc1, pDest, len, lenDest);
		Memory::ReleaseBuffer(mask, arr);
		return result;
	}
	u8 Bits::MultiplyFFTHigh8(u8*pDest, size_t lenDest, cu8* pm1, size_t len1, cu8*pm2, size_t len2)
	{
		if (len1 == 0 || len2 == 0) { memset(pDest, 0, lenDest*sizeof(u16)); return 0; }
		size_t len = ((size_t)1) << (sizeof(size_t) * 8 + 1 - LeftZeroCount((len1>len2 ? len1 : len2) - 1));
		unsigned char* arr;
		size_t mask = Memory::GetBuffer(sizeof(Math::DoubleComplex)*len * 2, &arr);
		Math::DoubleComplex* dc1 = (Math::DoubleComplex*)(unsigned char*)arr;
		Math::DoubleComplex* dc2 = dc1 + len;
		Math::DoubleComplex::FFTHigh8(pm1, dc1, len1, len);
		Math::DoubleComplex::FFTHigh8(pm2, dc2, len2, len);
		for (size_t i = 0; i < len; ++i)dc1[i] *= dc2[i];
		u8 result = Math::DoubleComplex::IFFTHigh8(dc1, pDest, len, lenDest);
		Memory::ReleaseBuffer(mask, arr);
		return result;
	}
	u16 Bits::MultiplyFFTLow(u16*pDest, size_t lenDest, cu16* pm1, size_t len1, cu16*pm2, size_t len2)
	{
		if (len1 == 0 || len2 == 0) { memset(pDest, 0, lenDest*sizeof(u16)); return 0; }
		size_t len = ((size_t)1) << (sizeof(size_t) * 8 + 1 - LeftZeroCount((len1>len2 ? len1 : len2) - 1));
		unsigned char* arr;
		size_t mask = Memory::GetBuffer(sizeof(Math::DoubleComplex)*len * 2, &arr);
		Math::DoubleComplex* dc1 = (Math::DoubleComplex*)arr;
		Math::DoubleComplex* dc2 = dc1 + len;
		Math::DoubleComplex::FFTLow(pm1, dc1, len1, len);
		Math::DoubleComplex::FFTLow(pm2, dc2, len2, len);
		for (size_t i = 0; i < len; ++i) { dc1[i] *= dc2[i]; }
		len = Math::DoubleComplex::IFFTLow(dc1, pDest, len, lenDest);
		Memory::ReleaseBuffer(mask, arr);
		return (u16)len;
	}
	u16 Bits::MultiplyFFTHigh(u16*pDest, size_t lenDest, cu16* pm1, size_t len1, cu16*pm2, size_t len2)
	{
		if (len1 == 0 || len2 == 0) { memset(pDest, 0, lenDest*sizeof(u16)); return 0; }
		size_t len = ((size_t)1) << (sizeof(size_t) * 8 + 1 - LeftZeroCount((len1>len2 ? len1 : len2) - 1));
		unsigned char* arr;
		size_t mask = Memory::GetBuffer(sizeof(Math::DoubleComplex)*len * 2, &arr);
		Math::DoubleComplex* dc1 = (Math::DoubleComplex*)(unsigned char*)arr;
		Math::DoubleComplex* dc2 = dc1 + len;
		Math::DoubleComplex::FFTHigh(pm1, dc1, len1, len);
		Math::DoubleComplex::FFTHigh(pm2, dc2, len2, len);
		for (size_t i = 0; i < len; ++i)dc1[i] *= dc2[i];
		len = Math::DoubleComplex::IFFTHigh(dc1, pDest, len, lenDest);
		Memory::ReleaseBuffer(mask, arr);
		return (u16)len;
	}
#endif
#ifdef COMPLEX128_
	u32 Bits::MultiplyFFTHigh32(u32 * pDest, size_t lenDest, cu32 * pm1, size_t len1, cu32 * pm2, size_t len2)
	{
		if (len1 == 0 || len2 == 0) { memset(pDest, 0, lenDest*sizeof(u32)); return 0; }
		size_t len = ((size_t)1) << (sizeof(size_t) * 8 + 1 - LeftZeroCount((len1>len2 ? len1 : len2) - 1));
		u8* arr;
		size_t mask = Memory::GetBuffer(sizeof(Math::Complex128)*len * 2, &arr);
		Math::Complex128* dc1 = (Math::Complex128*)(u8*)arr;
		Math::Complex128* dc2 = dc1 + len;
		Math::Complex128::FFTHigh(pm1, dc1, len1, len);
		Math::Complex128::FFTHigh(pm2, dc2, len2, len);
		for (size_t i = 0; i < len; ++i)dc1[i] *= dc2[i];
		u32 result = Math::Complex128::IFFTHigh(dc1, pDest, len, lenDest);
		Memory::ReleaseBuffer(mask, arr);
		return result;
	}
#endif

	u32 Bits::SelfDivideInt32Low32(u32 *p, size_t len, u32 num)
	{
		if (num == 0)return 0;
		u64 tmp = 0;
		size_t i = len;
		while (i != 0)
		{
			tmp |= p[--i];
			p[i] = (u32)(tmp / num);
			tmp = (u64)(tmp%num) << 32;
		}
		return tmp >> 32;
	}
	u32 Bits::SelfDivideInt32Low64(u64 *p, size_t len, u32 num)
	{
		if (num == 0)return 0;
		u64 tmp = 0;
		size_t i = len;
		while (i != 0)
		{
			tmp |= p[--i] >> 32;
			u64 t = (tmp / num) << 32;
			tmp = ((u64)(tmp%num) << 32) | (u32)p[i];
			p[i] = (tmp / num) | t;
			tmp = ((u64)(tmp%num) << 32);
		}
		return tmp >> 32;
	}
	u64 Bits::SelfDivideInt64Low32(u32 *p, size_t len, u64 num)
	{
		if (num == 0)return 0;
		u64 rt;
		if (len == 1) { rt = *p; *p = 0; return rt; }
		rt = 0;
		size_t i = len;
		while (i > 1)
		{
			i -= 2;
			*(u64*)(p + i) = Divide(rt, *(u64*)(p + i), num, &rt);
		}
		if (i != 0)
		{
			*p = (u32)Divide(rt >> 32, (rt << 32) | *p, num, &rt);
		}
		return rt;
	}
	u64 Bits::SelfDivideInt64Low64(u64 *p, size_t len, u64 num)
	{
		if (num == 0)return 0;
		u64 tmp = 0;
		size_t i = len;
		while (i != 0)
		{
			--i;
			p[i] = Divide(tmp, p[i], num, &tmp);
		}
		return tmp;
	}
	u32 Bits::SelfDivideInt32High32(u32 *p, size_t len, u32 num, bool mov)
	{
		if (num == 0 || len == 0)return 0;
		size_t i = len - 1;
		u64 tmp = ((u64)p[i]) << 32;;
		u64 result = 0;
		while (i != 0)
		{
			tmp |= p[--i];
			result = (result << 32) | (tmp / num);
			tmp = (u64)(tmp%num) << 32;
			p[i + 1] = (u32)(mov ? (result >> 1) : result);
		}
		result = (result << 32) | (tmp / num);
		p[0] = (u32)(mov ? (result >> 1) : result);
		return (u32)(mov ? ((tmp % (((u64)num) << 1)) >> 1) : tmp%num);
	}
	u64 Bits::SelfDivideInt64High64(u64 *p, size_t len, u64 num, bool mov)
	{
		if (num == 0 || len == 0)return 0;
		size_t i = len - 1;
		u64 tmp = p[i];
		u64 result[2];
		result[0] = tmp / num;
		while (i != 0)
		{
			result[1] = result[0];
			result[0] = Divide(tmp, p[--i], num, &tmp);
			p[i + 1] = mov ? (result[0] >> 1) | (result[1] << 63) : result[0];
		}
		result[1] = result[0];
		result[0] = Divide(tmp, 0, num, &tmp);
		p[0] = mov ? (result[0] >> 1) | (result[1] << 63) : result[0];
		if (mov)
		{
			if ((result[0] & 1) == 0)tmp >>= 1;
			else
			{
				mov = tmp > ~num;
				tmp += num;
				if (mov)tmp = (tmp >> 1) | (1ull << 63);
				else tmp >>= 1;
			}
		}
		return tmp;
	}
	u32 Bits::DivideInt32Low32(u32 *pDest, size_t lenDest, cu32*pSource, size_t lenSource, u32 num)
	{
		if (num == 0 || lenSource == 0) { for (size_t i = 0; i < lenDest; ++i)pDest[i] = 0; return 0; }
		u64 tmp = 0;
		size_t i = lenSource;
		if (lenDest > lenSource)
		{
			while (lenDest != lenSource)pDest[--lenDest] = 0;
		}
		while (i != 0)
		{
			tmp |= pSource[--i];
			if (i < lenDest)pDest[i] = (u32)(tmp / num);
			tmp = (u64)(tmp%num) << 32;
		}
		return tmp >> 32;
	}
	u64 Bits::DivideInt64Low64(u64 *pDest, size_t lenDest, cu64*pSource, size_t lenSource, u64 num)
	{
		if (num == 0 || lenSource == 0) { for (size_t i = 0; i < lenDest; ++i)pDest[i] = 0; return 0; }
		u64 tmp = 0;
		if (lenDest > lenSource)
		{
			while (lenDest != lenSource)pDest[--lenDest] = 0;
		}
		size_t i = lenSource;
		while (i != 0)
		{
			--i;
			u64 t = Divide(tmp, pSource[i], num, &tmp);
			if (i < lenDest)pDest[i] = t;
		}
		return tmp;
	}
	u32 Bits::DivideInt32High32(u32 *pDest, size_t lenDest, cu32*pSource, size_t lenSource, u32 num, bool mov)
	{
		if (num == 0 || lenSource == 0) { for (size_t i = 0; i < lenDest; ++i)pDest[i] = 0; return 0; }
		size_t i = lenSource - 1;
		if (lenDest == 0)
		{
			return (u32)(mov ? ((pSource[i] % (((u64)num) << 1)) | (pSource[i] & 1)) : pSource[i] % num);
		}
		u64 tmp = ((u64)pSource[i]) << 32;;
		size_t j = lenDest - 1;
		u64 result = 0;
		for (;;)
		{
			if (i != 0)tmp |= pSource[--i];
			result = (result << 32) | (tmp / num);
			pDest[j] = (u32)(mov ? (result >> 1) : result);
			if (i == 0 && tmp == 0 && result == 0)while (j != 0)pDest[--j] = 0;
			if (j == 0)break;
			tmp = (u64)(tmp%num) << 32;
			--j;
		}
		return (u32)(mov ? ((tmp >> 1) % num) : tmp%num);
	}
	u64 Bits::DivideInt64High64(u64 *pDest, size_t lenDest, cu64*pSource, size_t lenSource, u64 num, bool mov)
	{
		if (num == 0 || lenSource == 0) { for (size_t i = 0; i < lenDest; ++i)pDest[i] = 0; return 0; }
		size_t i = lenSource - 1;
		u64 tmp = pSource[i];
		u64 result[2];
		if (lenDest == 0)
		{
			if (mov)
			{
				return (((tmp >> 1) % num) << 1) | (tmp & 1);
			}
			return tmp%num;
		}
		size_t j = lenDest;
		result[0] = tmp / num;
		while (j != 0)
		{
			result[1] = result[0];
			result[0] = i == 0 ? Divide(tmp, 0, num, &tmp) : Divide(tmp, pSource[--i], num, &tmp);
			pDest[--j] = mov ? (result[0] >> 1) | (result[1] << 63) : result[0];
			if (i == 0 && tmp == 0 && result[0] == 0) { while (j != 0)pDest[--j] = 0; }
		}
		if (mov)
		{
			if ((result[0] & 1) == 0)tmp >>= 1;
			else
			{
				mov = tmp > ~num;
				tmp += num;
				if (mov)tmp = (tmp >> 1) | (1ull << 63);
				else tmp >>= 1;
			}
		}
		return tmp;
	}
	void Bits::DivideLow64(u64*p, size_t len, cu64 *p1, u64 bitsCount1, cu64*p2, u64 bitsCount2, u64* pd, size_t lend)
	{
		if (bitsCount2 == 0)return;
		//计算长度
		size_t len1 = (size_t)((bitsCount1 + 63) >> 6);
		size_t len2 = (size_t)((bitsCount2 + 63) >> 6);
		//除数比被除数大
		if (bitsCount2 > bitsCount1)
		{
			for (size_t i = 0; i < len; ++i)p[i] = 0;
			if (pd)//输出余数
			{
				for (size_t i = 0; i < lend&&i < len1; ++i)pd[i] = p1[i];
				for (size_t i = len1; i < lend; ++i)pd[i] = 0;
			}
			return;
		}
		//除数比较小的时候采用快速除法
		if (len2 == 1)
		{
			bitsCount2 = Bits::DivideInt64Low64(p, len, p1, len1, *p2);//输出结果并获取余数
			if (pd&&lend != 0) { *pd = bitsCount2; for (size_t i = 1; i < lend; ++i)pd[i] = 0; }//输出余数
			return;
		}
		//获取计算所需空间
		u8*buf;
		size_t mask = Memory::GetBuffer(sizeof(u64)*(len2 + 1) * 2, &buf);
		u64* pbuf1 = (u64*)(u8*)buf;//被除数内存
		u64* pbuf2 = pbuf1 + len2 + 1;//试商乘积
		 //第一次试商（非标准）
		size_t destlen = len1 - len2;
		u64 dq = 0;
		u64 q = 0;
		for (size_t i = destlen; i < len; ++i)p[i] = 0;//清理商的高位数据
		if (Bits::CompareHigh64(p1 + destlen, p2, len2, len2) >= 0)
		{
			Memory::Copy(pbuf1, p1 + destlen, len2*sizeof(u64));
			q = p1[len1 - 1] / (p2[len2 - 1] + 1);
			Bits::MultiplyInt64Low64(pbuf2, len2, p2, len2, q);
			Bits::SelfMinus64(pbuf1, len2, pbuf2, len2);
			while (Bits::CompareHigh64(pbuf1, p2, len2, len2) >= 0)
			{
				Bits::SelfMinus64(pbuf1, len2, p2, len2);
				++q;
			}
			if (destlen < len)p[destlen] = q;
			if (destlen != 0)
			{
				for (size_t i = len2; i != 0; --i)pbuf1[i] = pbuf1[i - 1];//左移64bit
				dq = ((bitsCount2 & 63) == 0 ? p2[len2 - 1] : ShiftLeft(p2[len2 - 1], p2[len2 - 2], 64 - (bitsCount2 & 63))) + 1;
			}
		}
		else//除数比被除数大
		{
			if (destlen != 0)
			{
				Memory::Copy(pbuf1 + 1, p1 + destlen, len2*sizeof(u64));
				dq = ((bitsCount2 & 63) == 0 ? p2[len2 - 1] : ShiftLeft(p2[len2 - 1], p2[len2 - 2], 64 - (bitsCount2 & 63))) + 1;
			}
			else
			{
				for (size_t i = 0; i < len; ++i)p[i] = 0;
				if (pd)
				{
					for (size_t i = 0; i < lend&&i < len1; ++i)pd[i] = p1[i];
					for (size_t i = len1; i < lend; ++i)pd[i] = 0;
				}
				Memory::ReleaseBuffer(mask, buf);
				return;
			}
		}
		while (destlen != 0)
		{
			destlen--;
			pbuf1[0] = p1[destlen];
			if (pbuf1[len2 - 1] != 0 || pbuf1[len2] != 0)
			{
				u64 h64 = (bitsCount2 & 63) == 0 ? pbuf1[len2] : ShiftLeft(pbuf1[len2], pbuf1[len2 - 1], 64 - (bitsCount2 & 63));
				q = dq == 0 ? h64 : Divide(h64, (bitsCount2 & 63) == 0 ? pbuf1[len2 - 1] : ShiftLeft(pbuf1[len2 - 1], pbuf1[len2 - 2], 64 - (bitsCount2 & 63)), dq);
				Bits::MultiplyInt64Low64(pbuf2, len2 + 1, p2, len2, q);//乘积
				Bits::SelfMinus64(pbuf1, len2 + 1, pbuf2, len2 + 1);//相减
				while (pbuf1[len2] != 0 || Bits::CompareHigh64(pbuf1, p2, len2, len2) >= 0)
				{
					Bits::SelfMinus64(pbuf1, len2 + 1, p2, len2);
					++q;
				}
			}
			else { q = 0; }
			if (destlen < len)p[destlen] = q;
			if (destlen != 0)for (size_t i = len2; i != 0; --i)pbuf1[i] = pbuf1[i - 1];//左移64bit
		}
		//结束部分，输出余数
		if (pd)
		{
			for (size_t i = 0; i < lend&&i < len2; ++i)pd[i] = pbuf1[i];
			for (size_t i = len2; i < lend; ++i)pd[i] = 0;
		}
		Memory::ReleaseBuffer(mask, buf);
	}
	void Bits::DivideHigh64(u64*p, size_t len, cu64*p1, u64 len1, cu64*p2, u64 len2, bool mov, u64 *pd, size_t lend)
	{
		//除数为0直接返回
		if (len2 == 0)return;
		//被除数为0直接全0
		if (p1 == NULL || len1 == 0)
		{
			if (p)for (size_t i = 0; i != len; ++i)p[i] = 0;
			if (pd)for (size_t i = 0; i != lend; ++i)pd[i] = 0;
			return;
		}
		//除数长度为1
		if (len2 == 1)
		{
			u64 tmp = Bits::DivideInt64High64(p, (size_t)len, p1, (size_t)len1, *p2, mov);
			if (pd && lend != 0)
			{
				pd[lend - 1] = tmp;
				size_t i = lend - 1;
				if (len1 > len)
				{
					size_t j = (size_t)(len1 - len - 1);
					if (!mov || len == 0)while (j != 0 && i != 0)pd[--i] = p1[--j];
					else
					{
						mov = (p1[j] & 1) && ((*p2 & 1) == 0 || (*p & 1) == 0);
						size_t k = i;
						while (j != 0 && i != 0)
						{
							--i; --j;
							pd[i] = (p1[j] >> 1) | (p1[j + 1] << 63);
						}
						if (i != 0)pd[--i] = j != 0 ? (p1[j] << 63) : 0;
						if (k != 0)
						{
							if (mov)pd[k - 1] |= (1ull << 63);
							else pd[k - 1] &= 0x7fffffffffffffff;
						}
					}
				}
				while (i != 0)pd[--i] = 0;
			}
			return;
		}
		if (pd == NULL)lend = 0;
		size_t tmp = len + lend + 1;
		//除数长度计算
		if (len2 > tmp) { p2 += len2 - tmp; len2 = tmp; }
		//生商位置到此停止左移
		size_t stop = (size_t)(len2 > lend ? len2 - lend - 1 : 0);

		//获取试商乘积内存(自动释放)
		unsigned char* buf;
		size_t mask = Memory::GetBuffer(sizeof(u64)*(size_t)(len2 + 1) * 2, &buf);
		u64* pbuf1 = (u64*)(unsigned char*)buf;
		u64* pbuf2 = (u64*)(unsigned char*)buf + len2 + 1;
		//第一次试商
		u64 q[2];
		//复制被除数内容到pbuf1
		tmp = (size_t)(len > stop + 1 ? len2 : len2 + len - stop - 1);
		for (size_t i = (size_t)len1, j = tmp + 1; i != 0 && j != 0;)
		{
			--i; --j;
			pbuf1[j] = p1[i];
		}
		if (tmp >= len1)for (size_t i = (size_t)(tmp - len1);;) { pbuf1[i] = 0; if (i == 0)break; --i; }
		if (Bits::CompareHigh64(p1, p2, (size_t)len1, (size_t)len2) >= 0)
		{
			if (tmp < len2)Bits::SelfMinus64(pbuf1, tmp + 1, p2 + len2 - tmp - 1, tmp + 1);
			else Bits::SelfMinus64(pbuf1 + 1, tmp, p2 + len2 - tmp, tmp);
			q[1] = 1;
		}
		else
		{
			q[1] = 0;
		}
		size_t destlen = len;//生商位置
		tmp = (size_t)(len1 < len2 ? 0 : len1 - len2);//取值位置
		u64 dq = p2[len2 - 1] + 1;//试商除数
		while (destlen != 0)
		{
			--destlen;
			size_t k;
			if (destlen >= stop)
			{
				k = (size_t)len2;
				pbuf1[0] = tmp == 0 ? 0 : p1[--tmp];
			}
			else
				k = (size_t)(len2 + destlen - stop);
			if (pbuf1[k] == 0 && pbuf1[k - 1] < p2[len2 - 1])
			{
				q[0] = 0;
				size_t i = k - 1;
				while (i != 0 && pbuf1[i] == 0)i--;
				if (pbuf1[i] == 0)//整除
				{
					for (i = destlen;;) { p[i] = 0; if (i == 0)break; --i; }
					if (pd)for (i = 0; i != lend; ++i)pd[i] = 0;
				}
			}
			else {
				q[0] = dq != 0 ? Divide(pbuf1[k], pbuf1[k - 1], dq) : pbuf1[k];
				Bits::MultiplyInt64Low64(pbuf2, k + 1, p2 + len2 - k, k, q[0]);
				Bits::SelfMinus64(pbuf1, k + 1, pbuf2, k + 1);
				while (pbuf1[k] != 0 || Bits::CompareHigh64(pbuf1, p2 + len2 - k, k, k) >= 0)
				{
					if (Bits::SelfMinus64(pbuf1, k + 1, p2 + len2 - k, k))pbuf1[k]--;
					q[0]++;
				}
			}

			//商赋值
			if (mov)p[destlen] = (q[0] >> 1) | (q[1] << 63);
			else p[destlen] = q[0];
			//商左移
			q[1] = q[0];
			//被除数左移64bit
			if (destlen > stop)for (size_t i = (size_t)len2; i != 0; --i)pbuf1[i] = pbuf1[i - 1];
		}
		//输出余数
		if (pd != NULL&&lend != 0)
		{
			len2 -= stop;
			p2 += stop;
			if (mov)
			{
				if ((q[1] & 1) != 0)
				{
					Bits::SelfPlus64(pbuf1, len2 + 1, p2, len2, 0);
				}
				for (size_t i = (size_t)len2, j = (size_t)lend; j != 0 && i != 0; --i)
				{
					pd[--j] = len == 0 ? pbuf1[i - 1] : ShiftRight(pbuf1[i], pbuf1[i - 1], 1);
				}
				if (lend > len2)
				{
					if (tmp != 0)pd[lend - len2 - 1] = (pbuf1[0] << 63) | (p1[--tmp] >> 1);
					else pd[lend - len2 - 1] = (pbuf1[0] << 63);
					size_t i = (size_t)(lend - len2 - 1);
					if (tmp != 0)while (i != 0)
					{
						if (tmp != 0)
							pd[--i] = (p1[tmp] << 63) | (p1[tmp - 1] >> 1);
						else
						{
							pd[--i] = (p1[tmp] << 63);
							break;
						}
						--tmp;
					}
					while (i != 0)pd[--i] = 0;
				}
			}
			else
			{
				for (size_t i = (size_t)len2, j = (size_t)lend; j != 0 && i != 0;)
					pd[--j] = pbuf1[--i];
				if (lend > len2)for (size_t i = (size_t)(lend - len2); i != 0;)pd[--i] = tmp == 0 ? 0 : p1[--tmp];
			}
		}
		Memory::ReleaseBuffer(mask, buf);
	}
	void Bits::ModHigh64(u64*p, size_t len, u64 bits, cu64*p1, u64 len1, cu64*p2, u64 len2, bool mov, u64 *pd, size_t lend)
	{
		//除数为0直接返回
		if (len2 == 0)return;
		//被除数为0直接全0
		if (len1 == 0)
		{
			if (p)for (size_t i = 0; i != len; ++i)p[i] = 0;
			if (pd)for (size_t i = 0; i != lend; ++i)pd[i] = 0;
			return;
		}
		//除数长度计算
		size_t tmp = (size_t)(((bits + 63) >> 6) + lend + 1);
		if (len2 > tmp) { p2 += len2 - tmp; len2 = tmp; }
		//获取试商乘积内存(自动释放)
		unsigned char* buf;
		size_t mask = Memory::GetBuffer(sizeof(u64)*(size_t)(len2 + 1) * 2, &buf);
		u64* pbuf1 = (u64*)(unsigned char*)buf;
		u64* pbuf2 = (u64*)(unsigned char*)buf + len2 + 1;
		if (bits == 0 && mov &&lend != 0)//直接写入余数
		{
			/*//按余数总小于除数原则右移复制
			pd[lend - 1] = p1[len1 - 1] >> 1;
			for (size_t i = lend - 1, j = len1 - 1; j != 0 && i != 0;)
			{
			--j; --i;
			pd[i] = (p1[j+1] << 63) | (p1[j]>>1);
			}
			if (lend > len1)
			{
			pd[lend - len - 1] = *p1 << 63;
			for (size_t i = 0; i < lend - len - 1; ++i)pd[i]=0;
			}*/
			for (size_t i = (size_t)lend, j = (size_t)len1; j != 0 && i != 0;)
			{
				--j; --i;
				pd[i] = p1[j];
			}
			for (size_t i = 0; i + len1 < lend; ++i)pd[i] = 0;
			if (len != 0)memset(p, 0, sizeof(u64)*len);
			Memory::ReleaseBuffer(mask, buf);
			return;
		}
		//开始试商
		u64 qarr[2] = { 0 };//商
		if (CompareHigh64(p1, p2, (size_t)len1, (size_t)len2) >= 0)
		{
			Bits::Minus64(pbuf1, len2 + 1, p1, len1, p2, len2, 64 * (s64)(len2 + 1 - len1), 64);
			if (bits == 0 || bits == (u64)mov)
			{
				if (len != 0)//商
				{
					if (mov)p[len - 1] = 1ull << 63;
					else p[len - 1] = 0;
					for (size_t i = len - 1; i != 0;)p[--i] = 0;
				}
				for (size_t i = (size_t)len2 + 1, j = (size_t)lend; i != 0 && j != 0;) { pd[--j] = pbuf1[--i]; }
				if (len1 > len2 && lend > len2)for (size_t i = (size_t)(len1 - len2 - 1), j = (size_t)(lend - len2 - 1); i != 0 && j != 0;) { pd[--j] = p1[--i]; }
				if (lend > len1)for (size_t i = 0; i < lend - len1; ++i)pd[i] = 0;
				Memory::ReleaseBuffer(mask, buf);
				return;
			}
			qarr[1] = 1;
		}
		else
		{
			if (bits == 0 || bits == (u64)mov)//直接写入余数
			{
				for (size_t i = len; i != 0;)p[--i] = 0;//商0
				for (size_t i = (size_t)len1, j = (size_t)lend; i != 0 && j != 0;) { pd[--j] = p1[--i]; }
				if (lend > len1)for (size_t i = 0; i < lend - len1; ++i)pd[i] = 0;
				Memory::ReleaseBuffer(mask, buf);
				return;
			}
			size_t i = (size_t)len1, j = (size_t)len2 + 1;
			while (i != 0 && j != 0) { pbuf1[--j] = p1[--i]; }
			while (j != 0)pbuf1[--j] = 0;
		}
		u64 q = p2[len2 - 1] + 1;//试商除数
		size_t index1 = (size_t)(len1 > len2 ? len1 - len2 : 0);
		tmp = len;
		for (;;)
		{
			pbuf1[0] = index1 == 0 ? 0 : p1[--index1];
			qarr[0] = q == 0 ? pbuf1[len2] : Divide(pbuf1[len2], pbuf1[len2 - 1], q);//试商
			if ((s64)bits < 64 + mov)
			{
				bits = 64 + mov - bits;
				qarr[0] &= ((u64)-1) << bits;
				Bits::MultiplyInt64Low64(pbuf2, (size_t)len2 + 1, p2, (size_t)len2, qarr[0]);
				Bits::SelfMinus64(pbuf1, len2 + 1, pbuf2, len2 + 1);
				while ((pbuf1[len2] >> bits) != 0 || Bits::Compare(pbuf1, bits, len2 * 64, p2) >= 0)
				{
					Bits::SelfMinus64(pbuf1, len2 + 1, p2, len2, bits);
					qarr[0] += 1ull << bits;
				}
				if (tmp != 0)
				{
					if (mov)p[--tmp] = (qarr[0] >> 1) | (qarr[1] << 63);
					else p[--tmp] = qarr[0];
				}
				break;
			}
			Bits::MultiplyInt64Low64(pbuf2, (size_t)len2 + 1, p2, (size_t)len2, qarr[0]);
			Bits::SelfMinus64(pbuf1, len2 + 1, pbuf2, len2 + 1);
			while (pbuf1[len2] != 0 || Bits::CompareHigh64(pbuf1, p2, (size_t)len2, (size_t)len2) >= 0)
			{
				if (Bits::SelfMinus64(pbuf1, len2 + 1, p2, len2))pbuf1[len2]--;
				qarr[0]++;
			}
			if (tmp != 0) {
				if (mov)p[--tmp] = (qarr[0] >> 1) | (qarr[1] << 63);
				else p[--tmp] = qarr[0];
			}
			for (size_t i = (size_t)len2; i != 0; --i)pbuf1[i] = pbuf1[i - 1];//左移64bit
			if ((bits -= 64) == (u64)mov) { bits = 0; break; }
			qarr[1] = qarr[0];
		}
		//完整商剩余部位
		while (tmp != 0)p[--tmp] = 0;
		//输出余数
		size_t i = (size_t)lend, j = (size_t)len2 + 1;
		while (i != 0 && j != 1)
		{
			--i; --j;
			if (bits == 0)pd[i] = pbuf1[j];
			else pd[i] = (pbuf1[j] << (64 - bits)) | (pbuf1[j - 1] >> bits);
		}
		if (i != 0)
		{
			if (bits != 0)
			{
				pd[--i] = (pbuf1[0] << (64 - bits)) | (index1 == 0 ? 0 : (p1[--index1] >> bits));
				if (index1 != 0)while (i != 0)
				{
					--i;
					if (index1 != 0) {
						pd[i] = (p1[index1] << (64 - bits)) | (p1[index1 - 1] >> bits);
						--index1;
					}
					else { pd[i] = p1[0] << (64 - bits); break; }
				}
			}
			else
			{
				while (i != 0 && index1 != 0)pd[--i] = p1[--index1];
			}
			while (i != 0)pd[--i] = 0;
		}
		Memory::ReleaseBuffer(mask, buf);
	}
	int Bits::CompareHigh64(cu64*p1, cu64*p2, size_t len1, size_t len2)
	{
		while (len1 != 0 && len2 != 0)
		{
			--len1; --len2;
			if (p1[len1] != p2[len2])return p1[len1] > p2[len2] ? 1 : -1;
		}
		if (len1 == 0) { for (size_t i = 0; i < len2; ++i)if (p2[i] != 0)return -1; return 0; }
		for (size_t i = 0; i < len1; ++i)if (p1[i] != 0)return 1;
		return 0;
	}
	void Bits::Move(void* p, u64 startBitPosition, u64 bitsCount, s64 mov)//将p指向的内存的startBitPosition比特位起bitsCount比特的数据进行mov比特位移，正为左移，负为右移
	{
		if (!p || !bitsCount || !mov)return;
		if (startBitPosition >= 8)return Bits::Move((unsigned char*)p + (startBitPosition >> 3), startBitPosition & 7, bitsCount, mov);
		if (mov > (s64)bitsCount || -mov > (s64)bitsCount)return Bits::Set(p, (index_t)startBitPosition, (size_t)bitsCount, false);//过度位移
		size_t bytes = (size_t)((startBitPosition + bitsCount + 7) >> 3);//影响字节数
		unsigned char c_start = *(unsigned char*)p;//起始字节
		unsigned char c_end = *((unsigned char*)p + bytes - 1);//终止字节
		if (mov & 7)
		{
			s64 Bmov = mov < 0 ? (-mov) >> 3 : mov >> 3;
			u64 tmp;//临时数据存放
			if (mov > 0)//左移
			{
				s64 i = bytes - Bmov;
				mov &= 7;
				while (i > 7)
				{
					Memory::Move(&tmp, (unsigned char*)p + i - 8, 8);
					tmp <<= mov;
					Memory::Move((unsigned char*)p + i + Bmov - 7, (unsigned char*)&tmp + 1, 7);
					i -= 7;
				}
				tmp = 0;
				Memory::Copy(&tmp, (unsigned char*)p, (size_t)i);
				tmp <<= mov;
				Memory::Copy((unsigned char*)p + Bmov, &tmp, (size_t)i);
				if (Bmov)memset(p, 0, (size_t)Bmov);
			}
			else//右移
			{
				s64 i = 0;
				mov = (-mov) & 7;
				while (i + Bmov + 8 <= (s64)bytes)
				{
					Memory::Copy(&tmp, (unsigned char*)p + i + Bmov, 8);
					tmp >>= mov;
					Memory::Copy((unsigned char*)p + i, &tmp, 7);
					i += 7;
				}
				tmp = 0;
				Memory::Copy(&tmp, (unsigned char*)p + i + Bmov, (size_t)(bytes - i - Bmov));
				tmp >>= mov;
				Memory::Copy((unsigned char*)p + i, &tmp, (size_t)(bytes - i - Bmov));
				if (Bmov)memset((unsigned char*)p + bytes - Bmov, 0, (size_t)Bmov);
			}
		}
		else
		{
			mov >>= 3;
			if (mov > 0)//左移
			{
				Memory::Move((unsigned char*)p + mov, p, bytes - (size_t)mov);
				memset(p, 0, (size_t)mov);
			}
			else//右移
			{
				Memory::Move(p, (unsigned char*)p - mov, bytes + (size_t)mov);
				memset((unsigned char*)p + bytes + mov, 0, (size_t)-mov);
			}
		}
		//首字节处理
		if (startBitPosition != 0)
			*(unsigned char*)p = (*(unsigned char*)p&(0xff << startBitPosition)) | (c_start & (0xff >> (8 - startBitPosition)));
		bitsCount = (bitsCount + startBitPosition) & 7;//尾字节处理
		if (bitsCount != 0)
			*((unsigned char*)p + bytes - 1) = (*((unsigned char*)p + bytes - 1) & (0xff >> (8 - bitsCount))) | (c_end & (0xff << bitsCount));
	}
	int Bits::Compare(void const* pSource, u64 startBitPositon, u64 bitsCount, void const* pDestination, u64 destinationBitPosition)//比较两串二进制序列大小，从高位往低位比较
	{
		u64 num1, num2;
		while (bitsCount)
		{
			if (bitsCount >= 64)
			{
				Bits::Copy(&num1, 0, pSource, (index_t)(startBitPositon + bitsCount - 64), 64); Bits::Copy(&num2, 0, pDestination, (index_t)(destinationBitPosition + bitsCount - 64), 64); bitsCount -= 64;
			}
			else { num1 = num2 = 0; Bits::Copy(&num1, 0, pSource, (index_t)startBitPositon, (size_t)bitsCount); Bits::Copy(&num2, 0, pDestination, (index_t)destinationBitPosition, (size_t)bitsCount); bitsCount = 0; }
			if (num1 > num2)return 1;
			if (num1 < num2)return -1;
		}
		return 0;
	}
	bool Bits::Plus64(u64 *pDes, cu64* pSource, size_t len)
	{
		size_t i = 0;
		bool flag = false;
		while (i < len)
		{
			if (flag)
			{
				flag = pDes[i] >= (MaxValues::UInt64 ^ pSource[i]);
				pDes[i] += pSource[i] + 1;
			}
			else
			{
				flag = pDes[i] >(MaxValues::UInt64 ^ pSource[i]);
				pDes[i] += pSource[i];
			}
			++i;
		}
		return flag;
	}
	void Bits::CopyShift64(cu64* pSource, size_t sLen, u64* pDest, size_t dLen, s64 mov)
	{
		size_t m;
		if (mov == 0)//不相对位移
		{
			m = sLen > dLen ? dLen : sLen;
			Memory::Move(pDest, pSource, sizeof(u64)*m);
			if (m < dLen)
			{
				pDest += m;
				while (m++ < dLen)*pDest++ = 0;
			}
			return;
		}
		if (mov > 0)//左移
		{
			//获取移动块数
			m = (size_t)(mov >> 6);
			if (m >= dLen)//移动后导致全部移除
			{
				while (dLen-- != 0)*pDest++ = 0;
				return;
			}
			mov &= 63;
			u64*pd = pDest + m;//目标起始写入位置
			size_t dl = dLen - m;//目标起始写入位置到末尾的块数
			size_t len = sLen > dl ? dl : sLen;//实际写入块数
			if (mov == 0)//移动数量刚好为整数块
			{
				if (pd > pSource)
				{
					pd += len;
					pSource += len;
					while (len-- != 0)*--pd = *--pSource;//复制数据
					while (m-- != 0)*--pd = 0;//左移，右端置0
					return;
				}
				if (pd < pSource)
				{
					while (len-- != 0)*pd++ = *pSource++;
					while (m-- != 0)*pDest++ = 0;//左移，右端置0
					return;
				}
				while (m-- != 0)*--pd = 0;//右端置0
				return;
			}
			if (pd >= pSource)
			{
				pd += len;
				pSource += len;

				if (len > 1)while (--len != 0)
				{
					--pd;
					--pSource;
					*pd = (*pSource << mov) | (*(pSource - 1) >> (63 ^ mov));
				}
				if (len != 0)
				{
					*--pd = (*(pSource - 1) << mov);
				}
				while (m-- != 0)*--pd = 0;//右端置0
				return;
			}
			//pd < pSource
			while (pDest != pd)*pDest++ = 0;//右端置0
			if (len != 0)
			{
				*pd = *pSource << mov;
			}
			if (len > 1)while (--len != 0)
			{
				*++pd = (*(pSource + 1) << mov) | (*pSource >> (63 ^ mov));
				++pSource;
			}
			return;
		}
		//mov<0
		mov = -mov;
		m = (size_t)(mov >> 6);
		if (m >= sLen)//移动后导致全部移除，由于目标左端不做处理，将直接返回
		{
			return;
		}
		mov &= 63;
		pSource += m;
		sLen -= m;
		size_t len = sLen > dLen ? dLen : sLen;
		if (mov == 0)//刚好移动整数块
		{
			if (pDest < pSource)
			{
				while (len-- != 0)*pDest++ = *pSource++;
				return;
			}
			if (pDest > pSource)
			{
				pDest += len;
				pSource += len;
				while (len-- != 0)*--pDest = *--pSource;
				return;
			}
			return;
		}
		//mov!=0
		if (pDest <= pSource)
		{
			if (len > 1)while (--len != 1)
			{
				*pDest++ = (*(pSource + 1) << (63 ^ mov)) | (*pSource >> mov);
				++pSource;
			}
			if (len != 0)
			{
				*pDest = *pSource >> mov;
			}
			return;
		}
		pDest += len;
		pSource += len;
		if (len != 0)
		{
			*--pDest = *--pSource >> mov;
		}
		if (len > 1)while (--len != 0)
		{
			--pDest;
			--pSource;
			*pDest = (*pSource >> mov) | (*(pSource + 1) << (63 ^ mov));
		}
		return;
	}
	u64 Bits::Move64(u64* p, size_t len, s64 mov)
	{
		if (mov == 0)return 0;
		size_t m;
		u64 result = 0;
		if (mov > 0)
		{
			m = (size_t)(mov >> 6);
			if (m >= len)
			{
				if (m == len)result = *p << (mov & 63);
				while (len-- != 0)*p++ = 0;
				return result;
			}
			mov &= 63;
			p += len;
			len -= m;
			if (mov == 0)
			{
				result = *(p - m);
				while (len-- != 0) { --p; *p = *(p - m); }
				while (m-- != 0) { *--p = 0; }
				return result;
			}
			result = len == 1 ? (*(p - m) << mov) : (*(p - m) << mov) | (*(p - m - 1) >> (64 - mov));
			while (--len != 0) { --p; *p = (*(p - m) << mov) | (*(p - m - 1) >> (64 - mov)); }
			--p; *p = (*(p - m) << mov);
			while (m-- != 0) { *--p = 0; }
			return result;
		}
		mov = -mov;
		m = (size_t)((u64)mov >> 6);
		if (m >= len)
		{
			if (m == len)result = *(p + m - 1) >> (mov & 63);
			while (len-- != 0)*p++ = 0;
			return result;
		}
		mov &= 63;
		len -= m;
		if (mov == 0)
		{
			result = *(p + m - 1);
			while (len-- != 0) { *p = *(p + m); ++p; }
			while (m-- != 0) { *p = 0; ++p; }
			return result;
		}
		result = len == 1 ? (*(p + m - 1) >> mov) : (*(p + m - 1) >> mov) | (*(p + m) << (64 - mov));
		while (--len != 0) { *p = (*(p + m) >> mov) | (*(p + m + 1) << (64 - mov)); ++p; }
		*p = (*(p + m) >> mov);
		while (m-- != 0) { *++p = 0; }
		return result;
	}
}